一、介绍
导航抽屉可以显示在屏幕的左右两侧,默认情况下是隐藏的,当用户用手指从边缘向另一侧滑动的时候,会在内容上方出现一个隐藏的面板,此时内容视图区域会变暗。当点击面板外部或者向原来的方向滑动的时候,导航抽屉就会消失。通常这个导航抽屉用来当作流行的侧滑菜单。
这个类就是DrawerLayout,该类位于V4包中。
android.support.v4.widget.DrawerLayout.
二、DrawerLayout的使用
直接将DrawerLayout作为根布局,然后其内部第一个View为内容区域,第二个View为左侧菜单,第三个View为右侧侧滑菜单,当前第三个是可选的。
第一个View的宽高应当设置为fill_parent。
第二、三个View需要设置android:layout_gravity="left",和android:layout_gravity="right";且一般高度设置为fill_parent,宽度为固定值,即侧滑菜单的宽度。
三、左侧菜单布局
使用列表视图ListView
reslayoutleft_menu.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/color"
android:paddingTop="5dp"
android:layout_marginTop="80dp"
>
</ListView>数组资源文件 resvaluesarrays.xml
<resources>
<string-array name="color" style="@style/textColor">
<item>红</item>
<item>橙</item>
<item>黄</item>
<item>绿</item>
</string-array>
</resources>四、右侧菜单布局 简单的四个图标加文字 reslayoutright_menu.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginBottom="20dp"
android:orientation="vertical" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/wode" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="扫一扫"
android:textColor="#ffffff" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginBottom="20dp"
android:orientation="vertical" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/saoma" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="讨论组"
android:textColor="#ffffff" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginBottom="20dp"
android:orientation="vertical" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/mobile" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="手机"
android:textColor="#ffffff" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginBottom="20dp"
android:orientation="vertical" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/dianhua" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="电话"
android:textColor="#ffffff" />
</LinearLayout>
</LinearLayout>五、主布局
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- 内容视图 -->
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/blue_sky" >
<Button
android:onClick="openRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#80DDF4D4"
android:text="右侧菜单" />
</RelativeLayout>
<!-- 左侧菜单 这里使用fragment -->
<fragment
android:name="com.example.drawerlayouttest.LeftMenuFragment"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_gravity="left"
android:tag="left"/>
<!-- 右侧菜单 -->
<fragment
android:name="com.example.drawerlayouttest.RightMenuFragment"
android:layout_width="80dp"
android:layout_height="fill_parent"
android:layout_gravity="right"
android:tag="right"/>
</android.support.v4.widget.DrawerLayout>六、Fragment实现,加载菜单布局
public class LeftMenuFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.left_menu, container, false);
}
}
public class RightMenuFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.right_menu, container, false);
}
}七、MainActivity类实现
public class MainActivity extends FragmentActivity {
private DrawerLayout mDrawer;
private View mLeft;
private ListView list;
private float mFirstX = 0; // 手指按下时的x坐标
private int mSensity = 30; // 菜单打开关闭的手势范围
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
list = (ListView) findViewById(R.id.list);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
mDrawer.closeDrawer(Gravity.START);
String text = parent.getItemAtPosition(position).toString();
Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
}
});
mDrawer = (DrawerLayout) findViewById(R.id.drawer);
mLeft = mDrawer.getChildAt(1);
initEvent();
}
private void initEvent() {
mDrawer.setDrawerListener(new DrawerListener() {
/**
* 当抽屉滑动状态改变的时候被调用
* 状态值是STATE_IDLE(闲置--0), STATE_DRAGGING(拖拽的--1), STATE_SETTLING(固定--2)中之一。
* 抽屉打开的时候,点击抽屉,drawer的状态就会变成STATE_DRAGGING,然后变成STATE_IDLE
*/
@Override
public void onDrawerStateChanged(int arg0) {
Log.i("drawer", "drawer的状态:" + arg0);
}
// 菜单滑动
@Override
public void onDrawerSlide(View arg0, float rate) {
// rate从0.0 ~ 1.0 菜单的显示率
// 可以设置菜单出现的效果 缩放、透明度变化 参考HorizontalScroll实现的菜单缩放
}
/**
* 当一个抽屉被完全打开的时候被调用
*/
@Override
public void onDrawerOpened(View arg0) {
Log.i("drawer", "抽屉被完全打开了!");
}<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
/**
* 当一个抽屉完全关闭的时候调用此方法
*/
@Override
public void onDrawerClosed(View arg0) {
Log.i("drawer", "抽屉被完全关闭了!");
}
});
}
/**
* DrawerLayout只支持边缘滑动打开菜单
* 通过判断手势滑动的距离来增加打开菜单的手势范围 在屏幕范围内滑动均可打开关闭菜单
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mFirstX = ev.getX();
break;
case MotionEvent.ACTION_MOVE:
float curX = ev.getX();
// 向右滑动 预期效果:关闭右侧菜单 或 打开左侧菜单
if(curX-mFirstX > mSensity){
// 如果右侧菜单打开则关闭
// 从左到右的阅读顺序中 left相当于start , right 相当于 end
if(mDrawer.isDrawerOpen(Gravity.END)){
mDrawer.closeDrawer(Gravity.END);
// 关闭右侧菜单后 允许 左侧菜单滑动出现
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.START);
}else{
mDrawer.openDrawer(Gravity.START);
// 关闭右侧菜单滑动出现
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.END);
}
}
// 向左滑动
else if(mFirstX-curX > mSensity){
// 如果左侧菜单打开则关闭
if(mDrawer.isDrawerOpen(Gravity.LEFT)){
mDrawer.closeDrawer(Gravity.LEFT);
// 关闭左侧菜单后 允许 右侧菜单滑动出现
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.RIGHT);
}else{
mDrawer.openDrawer(Gravity.RIGHT);
// 右侧菜单打开后 关闭 左侧菜单滑动出现
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.LEFT);
}
}
default:
break;
}
return super.dispatchTouchEvent(ev);
}
public void openRight(View view)
{
mDrawer.openDrawer(Gravity.RIGHT);// 展开侧边的菜单
}
}八、项目运行图
项目下载地址