DrawerLayout侧滑菜单

DrawerLayout是support.v4包中实现侧滑菜单效果的控件,之前实现侧滑使用的是SlidingMenu,下面我主要介绍一下DrawerLayout控件。
DrawerLayout的使用非常方便,具体的使用如下所示:
1,drawerLayout 其实就是一个布局控件,跟RelativeLayout差不多,单是drawerLayout是带有侧滑效果的控件。drawerLayout布局里面可以包含两个布局,主内容布局和侧滑布局。
其中主内容布局要写在侧滑布局的前面。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:andro>
    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)在这里的作用。这也是我刚开始最疑惑的地方效果如下所示。

        DrawerLayout侧滑菜单

补充

补充一些东西:前几天做主题切换,发现结合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();
                    }
                });

  这样我们就更换了图标

    DrawerLayout侧滑菜单



项目地址:http://download.csdn.net/detail/jingsummer/9400400