DrawerLayout是support.v4包中实现侧滑菜单效果的控件,之前实现侧滑使用的是SlidingMenu,下面我主要介绍一下DrawerLayout控件。
DrawerLayout的使用非常方便,具体的使用如下所示:
1,drawerLayout 其实就是一个布局控件,跟RelativeLayout差不多,单是drawerLayout是带有侧滑效果的控件。drawerLayout布局里面可以包含两个布局,主内容布局和侧滑布局。
其中主内容布局要写在侧滑布局的前面。
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/id_drawerlayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.example.mgsd.myapplication.MainActivity" tools:showIn="@layout/activity_main"> <-- 主内容布局 --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_green_dark"> <ImageView android:id="@+id/iv_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" /> </LinearLayout>
<-- 侧滑布局 --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="@android:color/holo_red_dark"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:foregroundGravity="left"></ListView> </LinearLayout> </android.support.v4.widget.DrawerLayout>
注:在侧滑菜单的布局部分,一定要设置android:layout_gravity属性,来设置菜单是从左侧还是右侧滑出,一般设置android:layout_gravity="start"属性,从左侧滑出。
2,drawerLayout菜单的展开和隐藏可以被DrawerLayout.DrawerListener监听到,所以可以再打开和关闭的时候完成自己的逻辑,但是如果你还是用Toolbar,建议使用
ActionBarDrawerToggle 来监听侧滑菜单的打开和关闭,ActionBarDrawerToggle实现了DrawerListener,所以他能做DrawerListener可以做的任何事情,同时他还能将drawerLayout的展开和隐藏与actionbar的app 图标关联起来,当展开与隐藏的时候图标有一定的动画效果,点击图标的时候还能展开或者隐藏菜单。
mDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawopen, R.string.drawclose) { @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); toolbar.setTitle("侧滑栏");//弹出菜单修改toolbar的title } @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); toolbar.setTitle("APP FrameWork"); } }; mDrawerToggle.syncState(); drawerLayout.setDrawerListener(mDrawerToggle);
3,侧滑菜单内容。
侧滑菜单里面可以是任何形式,完全自己设置,例如,上面的布局中我们设置了listview,那样我们就可以在侧滑菜单中展示listview或者更简单的布局,像是展示图片,文字等。也可以在侧滑菜单中加载Fragment,然后操作fragment,如下所示:
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="@android:color/holo_red_dark"> <FrameLayout android:id="@+id/framlayout" android:layout_width="match_parent" android:layout_height="match_parent" android:foregroundGravity="left"></FrameLayout> </LinearLayout>
然后创建一个Fragment,使用getSupportFragmentManager().beginTransaction().add(R.id.framlayout, new Fragment()).commit();将Fragment添加到侧滑菜单中。
4,主动展开和隐藏菜单栏的方法:
DrawerLayout.closeDrawer方法用于隐藏侧边菜单,DrawerLayout.openDrawer方法用于展开侧边菜单
5.如何在菜单展开或者隐藏的时候更新activity的menu
上面的的第2点讲到DrawerLayout.DrawerListener监听展开与隐藏事件,在监听的回调方法中我们用invalidateOptionsMenu通知activity重绘menu,然后activity就有机会在onPrepareOptionsMenu方法中更新menu元素的显示与隐藏
代码:
/* Called whenever we call invalidateOptionsMenu() */ @Override public boolean onPrepareOptionsMenu(Menu menu) { // If the nav drawer is open, hide action items related to the content view boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_websearch).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); }
6.如何让app图标点击的时候能够展开或者隐藏侧边菜单。
一般的想法是在activity的onOptionsItemSelected方法中判断点击事件是否来自于app图标,然后用DrawerLayout.closeDrawer和DrawerLayout.openDrawer来隐藏与展开(参见第4点:在代码中主动展开与隐藏侧边菜单)。但是drawerLayout提供了更优雅的方式:使用ActionBarDrawerToggle的onOptionsItemSelected方法。该方法activity的onOptionsItemSelected方法中根据传递进来的menu item做了上面我们在“一般想法”中提到的事情。用官方的说法是”ActionBarDrawerTogglewill take care of this”。我们只需这样做就ok了:
Activity中:
@Override public booleanonOptionsItemSelected(MenuItem item) { // The action bar home/up actionshould open or close the drawer. // ActionBarDrawerToggle will takecare of this. if(mDrawerToggle.onOptionsItemSelected(item)) { return true; } ……….//处理其他菜单点击事件 returnsuper.onOptionsItemSelected(item); }
如果不仔细阅读官方文档,估计我们很难看出(mDrawerToggle.onOptionsItemSelected(item)在这里的作用。这也是我刚开始最疑惑的地方效果如下所示。
补充
补充一些东西:前几天做主题切换,发现结合Toobar和 DrawerLayout使用在左上角会自动生成一个三个横杠的图标,由于项目需求,我需要将其改为自定义图标:然后我查看了ActionBarDrawerToggle的源码发现:
/** * Enable or disable the drawer indicator. The indicator defaults to enabled. * * <p>When the indicator is disabled, the <code>ActionBar</code> will revert to displaying * the home-as-up indicator provided by the <code>Activity</code>'s theme in the * <code>android.R.attr.homeAsUpIndicator</code> attribute instead of the animated * drawer glyph.</p> * * @param enable true to enable, false to disable */ public void setDrawerIndicatorEnabled(boolean enable) { if (enable != mDrawerIndicatorEnabled) { if (enable) { setActionBarUpIndicator((Drawable) mSlider, mDrawerLayout.isDrawerOpen(GravityCompat.START) ? mCloseDrawerContentDescRes : mOpenDrawerContentDescRes); } else { setActionBarUpIndicator(mHomeAsUpIndicator, 0); } mDrawerIndicatorEnabled = enable; } }
看上面的意思是 使用或者禁止使用系统图标。
然后也就是说enable是true的时候会走系统的逻辑,展示的是系统图标,这就是很多人为什么设置actionbar的setHomeAsUpIndicator也不好使的原因,所以我们需要两步:
mDrawerToggle.setDrawerIndicatorEnabled(false);//设置为false时显示自己设置的图标 actionBar.setHomeAsUpIndicator(//自己的图标);
然后这个时候因为屏蔽了系统操作,所以此时点击图标是不会滑出侧滑栏的,我们需要自己添加点击侧滑功能:
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() { @Override public void onClick(View v) { openDrawerLayout(); } });
这样我们就更换了图标
项目地址:http://download.csdn.net/detail/jingsummer/9400400