其实一种好的UI布局,可以使用户感到更加的亲切与方便。最近非常流行的莫过于侧边栏了,其实我也做过很多侧边栏的应用,但是那些侧边栏的使用我都不是很满意,现在重新整理,重新写了一个相对来说我比较满意的侧边栏,其中运用的就是android3.0版本之后新加的Fragment碎片化,碎片化的使用将来也是一个趋势,所以通过我这个程序你既可以学到侧边栏,也能让你更加熟悉碎片化的使用,一举两得的事。哈哈……废话不多说了,直接上图。图片如下:
①、自定义一个View,把左侧边栏视图,中间内容视图,右侧边栏视图放在里面,这里给这个View起名叫:SlidingMenu.java
代码如下:
package net.loonggg.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
public class SlidingMenu extends RelativeLayout {
private SlidingView mSlidingView;
private View mMenuView;
private View mDetailView;
public SlidingMenu(Context context) {
super(context);
}
public SlidingMenu(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void addViews(View left, View center, View right) {
setLeftView(left);
setRightView(right);
setCenterView(center);
}
/**
* 添加左侧边栏的view
*
* @param view
*/
@SuppressWarnings("deprecation")
public void setLeftView(View view) {
LayoutParams behindParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.FILL_PARENT);
behindParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);// 在父控件的左边
addView(view, behindParams);
mMenuView = view;
}
/**
* 添加右侧边栏的view
*
* @param view
*/
@SuppressWarnings("deprecation")
public void setRightView(View view) {
LayoutParams behindParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.FILL_PARENT);
behindParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);// 在父控件的右边
addView(view, behindParams);
mDetailView = view;
}
/**
* 添加中间内容的view
*
* @param view
*/
@SuppressWarnings("deprecation")
public void setCenterView(View view) {
LayoutParams aboveParams = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
mSlidingView = new SlidingView(getContext());
mSlidingView.setView(view);
addView(mSlidingView, aboveParams);
mSlidingView.setMenuView(mMenuView);
mSlidingView.setDetailView(mDetailView);
mSlidingView.invalidate();
}
public void showLeftView() {
mSlidingView.showLeftView();
}
public void showRightView() {
mSlidingView.showRightView();
}
}
代码如下:
package net.loonggg.view;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Scroller;
public class SlidingView extends ViewGroup {
private FrameLayout mContainer;
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private int mTouchSlop;
private float mLastMotionX;
private float mLastMotionY;
private static final int SNAP_VELOCITY = 1000;
private View mMenuView;
private View mDetailView;
public SlidingView(Context context) {
super(context);
init();
}
public SlidingView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SlidingView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mContainer.measure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int width = r - l;
final int height = b - t;
mContainer.layout(0, 0, width, height);
}
private void init() {
mContainer = new FrameLayout(getContext());
mContainer.setBackgroundColor(0xff000000);
mScroller = new Scroller(getContext());
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
super.addView(mContainer);
}
public void setView(View v) {
if (mContainer.getChildCount() > 0) {
mContainer.removeAllViews();
}
mContainer.addView(v);
}
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
postInvalidate();
}
@Override
public void computeScroll() {
if (!mScroller.isFinished()) {
if (mScroller.computeScrollOffset()) {
int oldX = getScrollX();
int oldY = getScrollY();
int x = mScroller.getCurrX();
int y = mScroller.getCurrY();
if (oldX != x || oldY != y) {
scrollTo(x, y);
}
// Keep on drawing until the animation has finished.
invalidate();
} else {
clearChildrenCache();
}
} else {
clearChildrenCache();
}
}
private boolean mIsBeingDragged;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
mLastMotionX = x;
mLastMotionY = y;
mIsBeingDragged = false;
break;
case MotionEvent.ACTION_MOVE:
final float dx = x - mLastMotionX;
final float xDiff = Math.abs(dx);
final float yDiff = Math.abs(y - mLastMotionY);
if (xDiff > mTouchSlop && xDiff > yDiff) {
mIsBeingDragged = true;
mLastMotionX = x;
}
break;
}
return mIsBeingDragged;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
final int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
mLastMotionX = x;
mLastMotionY = y;
if (getScrollX() == -getMenuViewWidth()
&& mLastMotionX < getMenuViewWidth()) {
return false;
}
if (getScrollX() == getDetailViewWidth()
&& mLastMotionX > getMenuViewWidth()) {
return false;
}
break;
case MotionEvent.ACTION_MOVE:
if (mIsBeingDragged) {
enableChildrenCache();
final float deltaX = mLastMotionX - x;
mLastMotionX = x;
float oldScrollX = getScrollX();
float scrollX = oldScrollX + deltaX;
if (deltaX < 0 && oldScrollX < 0) { // left view
final float leftBound = 0;
final float rightBound = -getMenuViewWidth();
if (scrollX > leftBound) {
scrollX = leftBound;
} else if (scrollX < rightBound) {
scrollX = rightBound;
}
// mDetailView.setVisibility(View.INVISIBLE);
// mMenuView.setVisibility(View.VISIBLE);
} else if (deltaX > 0 && oldScrollX > 0) { // right view
final float rightBound = getDetailViewWidth();
final float leftBound = 0;
if (scrollX < leftBound) {
scrollX = leftBound;
} else if (scrollX > rightBound) {
scrollX = rightBound;
}
// mDetailView.setVisibility(View.VISIBLE);
// mMenuView.setVisibility(View.INVISIBLE);
}
scrollTo((int) scrollX, getScrollY());
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (mIsBeingDragged) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int velocityX = (int) velocityTracker.getXVelocity();
velocityX = 0;
Log.e("ad", "velocityX == " + velocityX);
int oldScrollX = getScrollX();
int dx = 0;
if (oldScrollX < 0) {
if (oldScrollX < -getMenuViewWidth() / 2
|| velocityX > SNAP_VELOCITY) {
dx = -getMenuViewWidth() - oldScrollX;
} else if (oldScrollX >= -getMenuViewWidth() / 2
|| velocityX < -SNAP_VELOCITY) {
dx = -oldScrollX;
}
} else {
if (oldScrollX > getDetailViewWidth() / 2
|| velocityX < -SNAP_VELOCITY) {
dx = getDetailViewWidth() - oldScrollX;
} else if (oldScrollX <= getDetailViewWidth() / 2
|| velocityX > SNAP_VELOCITY) {
dx = -oldScrollX;
}
}
smoothScrollTo(dx);
clearChildrenCache();
}
break;
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
return true;
}
private int getMenuViewWidth() {
if (mMenuView == null) {
return 0;
}
return mMenuView.getWidth();
}
private int getDetailViewWidth() {
if (mDetailView == null) {
return 0;
}
return mDetailView.getWidth();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public View getDetailView() {
return mDetailView;
}
public void setDetailView(View mDetailView) {
this.mDetailView = mDetailView;
}
public View getMenuView() {
return mMenuView;
}
public void setMenuView(View mMenuView) {
this.mMenuView = mMenuView;
}
// void toggle() {
// int menuWidth = mMenuView.getWidth();
// int oldScrollX = getScrollX();
// if (oldScrollX == 0) {
// smoothScrollTo(-menuWidth);
// } else if (oldScrollX == -menuWidth) {
// smoothScrollTo(menuWidth);
// }
// }
/**
* 左侧边栏的关闭与显示
*/
public void showLeftView() {
int menuWidth = mMenuView.getWidth();
int oldScrollX = getScrollX();
if (oldScrollX == 0) {
smoothScrollTo(-menuWidth);
} else if (oldScrollX == -menuWidth) {
smoothScrollTo(menuWidth);
}
}
/**
* 右侧边栏的关闭与显示
*/
public void showRightView() {
int menuWidth = mDetailView.getWidth();
int oldScrollX = getScrollX();
if (oldScrollX == 0) {
smoothScrollTo(menuWidth);
} else if (oldScrollX == menuWidth) {
smoothScrollTo(-menuWidth);
}
}
void smoothScrollTo(int dx) {
int duration = 500;
int oldScrollX = getScrollX();
mScroller.startScroll(oldScrollX, getScrollY(), dx, getScrollY(),
duration);
invalidate();
}
void enableChildrenCache() {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View layout = (View) getChildAt(i);
layout.setDrawingCacheEnabled(true);
}
}
void clearChildrenCache() {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View layout = (View) getChildAt(i);
layout.setDrawingCacheEnabled(false);
}
}
}
package net.loonggg.fragment;
import net.loonggg.view.SlidingMenu;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.Window;
public class MainActivity extends FragmentActivity {
private SlidingMenu mSlidingMenu;// 侧边栏的view
private LeftFragment leftFragment; // 左侧边栏的碎片化view
private RightFragment rightFragment; // 右侧边栏的碎片化view
private SampleListFragment centerFragment;// 中间内容碎片化的view
private FragmentTransaction ft; // 碎片化管理的事务
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 去标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mSlidingMenu = (SlidingMenu) findViewById(R.id.slidingMenu);
mSlidingMenu.setLeftView(getLayoutInflater().inflate(
R.layout.left_frame, null));
mSlidingMenu.setRightView(getLayoutInflater().inflate(
R.layout.right_frame, null));
mSlidingMenu.setCenterView(getLayoutInflater().inflate(
R.layout.center_frame, null));
ft = this.getSupportFragmentManager().beginTransaction();
leftFragment = new LeftFragment();
rightFragment = new RightFragment();
ft.replace(R.id.left_frame, leftFragment);
ft.replace(R.id.right_frame, rightFragment);
centerFragment = new SampleListFragment();
ft.replace(R.id.center_frame, centerFragment);
ft.commit();
}
public void llronclick(View v) {
switch (v.getId()) {
case R.id.llr_energy_management:
Intent intent = new Intent(this, DetailsActivity.class);
startActivity(intent);
break;
default:
break;
}
}
public void showLeft() {
mSlidingMenu.showLeftView();
}
public void showRight() {
mSlidingMenu.showRightView();
}
}
package net.loonggg.fragment;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class SampleListFragment extends ListFragment {
private ImageView lv_left;
private ImageView iv_right;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mView = inflater.inflate(R.layout.list, null);
lv_left = (ImageView) mView.findViewById(R.id.iv_left);
iv_right = (ImageView) mView.findViewById(R.id.iv_right);
return mView;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Map item1 = new HashMap();
item1.put("list_title", getString(R.string.title1));
item1.put("list_image", R.drawable.p1);
item1.put("list_contect", getString(R.string.test));
Map item2 = new HashMap();
item2.put("list_title", getString(R.string.title1));
item2.put("list_image", R.drawable.p2);
item2.put("list_contect", getString(R.string.test));
Map item3 = new HashMap();
item3.put("list_title", getString(R.string.title1));
item3.put("list_image", R.drawable.p3);
item3.put("list_contect", getString(R.string.test));
Map item4 = new HashMap();
item4.put("list_title", getString(R.string.title1));
item4.put("list_image", R.drawable.p4);
item4.put("list_contect", getString(R.string.test));
Map item5 = new HashMap();
item5.put("list_title", getString(R.string.title1));
item5.put("list_image", R.drawable.p5);
item5.put("list_contect", getString(R.string.test));
Map item6 = new HashMap();
item6.put("list_title", getString(R.string.title1));
item6.put("list_image", R.drawable.p6);
item6.put("list_contect", getString(R.string.test));
Map item7 = new HashMap();
item7.put("list_title", getString(R.string.title1));
item7.put("list_image", R.drawable.p7);
item7.put("list_contect", getString(R.string.test));
List
其相应的布局文件代码如下:list.xml:
package net.loonggg.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
public class LeftFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.left_fragment, null);
LinearLayout userLayout = (LinearLayout) view
.findViewById(R.id.userLayout);
userLayout.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
UserFragment user = new UserFragment();
FragmentTransaction ft = getActivity()
.getSupportFragmentManager().beginTransaction();
ft.replace(R.id.center_frame, user);
ft.commit();
((MainActivity) getActivity()).showLeft();
}
});
LinearLayout mainPage = (LinearLayout) view.findViewById(R.id.mainPage);
mainPage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction ft = getActivity()
.getSupportFragmentManager().beginTransaction();
ft.replace(R.id.center_frame, new SampleListFragment());
ft.commit();
((MainActivity) getActivity()).showLeft();
}
});
return view;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
package net.loonggg.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class RightFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.right_fragment, null);
return view;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
package net.loonggg.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class UserFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.user, null);
ImageView left = (ImageView) view.findViewById(R.id.iv_user_left);
left.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
((MainActivity) getActivity()).showLeft();
}
});
return view;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
DetailsActivity.java:
package net.loonggg.fragment;
import android.app.Activity;
import android.os.Bundle;
public class DetailsActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details);
}
}
碎片化侧边栏
Settings
这种导弹的平均航速为5倍音速
这种导弹的平均航速为5倍音速
这种导弹的平均航速为5倍音速
这种导弹的平均航速为5倍音速
这种导弹的平均航速为5倍音速
这种导弹的平均航速为5倍音速
这种导弹的平均航速为5倍音速
美国《空军》杂志、西班牙《世界报》等媒体报道,美军计划在今年内多次试射高超音速导弹,从而将其作为威慑中俄的强力武器。有外媒指出,解放军已开发出可拦截高速导弹的防控系统,而且有潜力进一步开发拦截高超音速导弹的防空武器。
美国《空军》杂志报道,美军将在2013年继续试射高超音速巡航导弹,这种导弹的平均航速为5倍音速,最高瞬时航速达到7倍音速。对于目前全球所有的防卫系统来说,它都是无法防御的导弹。美国《防务新闻》更是声称,美军的“高超音速攻击时代”即将来临,目前各国军队尚无能力对这种高速攻击目标进行有效拦截,任何导弹防御系统在它面前都形同虚设。
西班牙《世界报》报道,从2013年3月到12月,美军可能进行3次重要的实验,如果一切顺利,美军可能于2014年尝试装备少量的高超音速导弹,这种导弹有望在未来5年内形成战斗力。
报道认为,美军高超音速导弹所形成的威胁以及对世界格局的影响难以估量。美国可能在一些“敏感区域”部署这种导弹,例如东亚地区,而朝鲜和伊朗的核设施也可能成为它的攻击目标。报道强调,美军高超音速导弹的主要作用是对其他军事大国实施威慑,主要是中国和俄罗斯。
据俄罗斯《军工信使》周刊指出,解放军在防范超音速导弹攻击方面“已经追赶上来”,中国某国防工业公开发的代号为LD-2000的陆基防空系统,已经被证实具备实战能力。这种防空系统可为高价值目标,包括指挥所、弹道导弹发射装置等提供保护。LD-2000防空系统发射的导弹拦截高速飞行的导弹和飞机,尤其擅长对付雷达反射面积较小的隐身巡航导弹及高速巡航导弹。报道揣测,它可以准确拦截飞行速度超过两倍音速的超音速导弹。通过改进其控制软件,该系统还可用来拦截高速火箭弹和迫击炮弹。
报道称,LD-2000系统可加装在军用卡车底盘上,从而实现机动部署,在需要它的地方构建防范超音速导弹的密集导弹阵。这种导弹集群的火力可与美军著名的“密集阵”(专门防御来袭空中目标的防空导弹集群)媲美。
报道称,LD-2000是一款针对出口市场的产品,解放军肯定同步开发了自用型号,而且其性能必然优于LD-2000,应该可以防范速度更快的来袭目标,例如航速达到三四倍音速的巡航导弹。报道认为,这表明解放军有能力开发用来对付美军高超音速导弹的防御系统。
源代码