MD系列2、ToolBar+DrawerLayout + NavigationView

本文出自 “阿敏其人” 简书博客,转载或引用请注明出处。

一、Google口中的ToolBar

从Toolbar说起
ToolBar->android.support.v7.widget.Toolbar
Toolbar是在Android 5.0以后推出来的,之前都是ActionBar这个控件

Paste_Image.png

Google Toolbar 文档

Google大概这么说

A standard toolbar for use within application content.

A Toolbar is a generalization of action bars for use within application layouts. While an action bar is traditionally part of an Activity's opaque window decor controlled by the framework, a Toolbar may be placed at any arbitrary level of nesting within a view hierarchy. An application may choose to designate a Toolbar as the action bar for an Activity using the setSupportActionBar() method.

Toolbar supports a more focused feature set than ActionBar. From start to end, a toolbar may contain a combination of the following optional elements:

  • A navigation button. This may be an Up arrow, navigation menu toggle, close, collapse, done or another glyph of the app's choosing. This button should always be used to access other navigational destinations within the container of the Toolbar and its signified content or otherwise leave the current context signified by the Toolbar. The navigation button is vertically aligned within the Toolbar's minimum height, if set.
  • A branded logo image. This may extend to the height of the bar and can be arbitrarily wide.
  • A title and subtitle. The title should be a signpost for the Toolbar's current position in the navigation hierarchy and the content contained there. The subtitle, if present should indicate any extended information about the current content. If an app uses a logo image it should strongly consider omitting a title and subtitle.
  • One or more custom views. The application may add arbitrary child views to the Toolbar. They will appear at this position within the layout. If a child view's Toolbar.LayoutParams indicates a Gravity value of CENTER_HORIZONTAL the view will attempt to center within the available space remaining in the Toolbar after all other elements have been measured.
  • An action menu. The menu of actions will pin to the end of the Toolbar offering a few frequent, important or typical actions along with an optional overflow menu for additional actions. Action buttons are vertically aligned within the Toolbar's minimum height, if set.

In modern Android UIs developers should lean more on a visually distinct color scheme for toolbars than on their application icon. The use of application icon plus title as a standard layout is discouraged on API 21 devices and newer.

其实大概是这个意思

Toolbar 是一个应用程序使用中的标准工具栏,Toolbar可以被嵌套在任意一个层级的View中。
相对ActionBar而言,Toolbar提供了更多牛逼的特性。ToolBar是api21 新增的组件,其主要用来弥补actionbar带来的不足,其继承自viewgroup,自由的属性包括:

  • 导航按钮(类似向上按钮) (A navigation button)
  • logo图片 (A branded logo image.)
  • 标题和子标题 (A title and subtitle)
  • 一个或者多个自定义view (One or more custom views.)
  • 菜单。 (An action menu.)
Paste_Image.png

需要特别注意的是:我们可以在任何activity中使用toolbar作为actiobar,但是api21之前只能使用setSupportActionbar(),相应的主题也要设置为NoActionbar.

二、简单实用

最简单的使用

1、引入库
build.gradle

    compile 'com.android.support:appcompat-v7:23.4.0'

2、Actviity继承自AppCompatActivity

public class MainActivity extends AppCompatActivity

3、Theme需要NoActionBar

<resources>

    <!-- Base application theme. -->
<!--    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!– Customize your theme here. –>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>-->

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

(如果Theme NoActionBar觉得不方便可以利用BaseActivity通知代码设置一下,supportRequestWindowFeature(Window.FEATURE_NO_TITLE) )

4、布局实用ToolBar

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="com.am.toolbartest.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/mToolBar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        >
    </android.support.v7.widget.Toolbar>
</RelativeLayout>

5、Activity setSupportActionBar

public class MainActivity extends AppCompatActivity {
    private Toolbar mToolBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolBar = (Toolbar) findViewById(R.id.mToolBar);
        setSupportActionBar(mToolBar);
    }
}

注意:
ToolBar需要调用setSupportActionBar(ToolBar);方法,如果你的Activity是继承自FragmentActivity,是没有这个方法的。
解决方案:将你的Activity改成继承自AppCompatActivity,(AppCompatActivity是FragmentActivity的直接子类)

运行效果:


Paste_Image.png

是的现在看起来low且平凡,现在先放任不管,把一些陌生的东西集中处理一下:

问题1、为什么style布局文件需要NoActionBar?
如果含有ActionBar,会和ToolBar冲突。所以必须在Style或者代码指定,去掉ActionBar。

问题2、布局文件android:elevation="4dp" 是什么鬼?

android:elevation有海拔和立体的意思,大概就是有一点浮动的效果,更加美观,不喜可删。
material design 建议为app bar 的elevation设置为4dp。

问题3、 指定ToolBar的主题: android:theme="@style/ThemeOverlay.AppCompat.ActionBar"和app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 是什么鬼?

android:theme="@style/ThemeOverlay.AppCompat.ActionBar",通过这句代码,我们可以为不同页面的ActionBar指定不同的主题样式

app:popupTheme="@style/ThemeOverlay.AppCompat.Light",这锅这句代码,可以指定弹出的菜单的样式

如果不加这两句代码,那么就是统一的默认主题样式。
详情可以参考一下链接:
正确使用 Android 的 Theme 和 Style
android:theme和app:popupTheme的作用,以及在android 3.0以下不起作用问题的解决

问题4、ToolBar的名字为何自带标题?

在运行效果图图里面,我们看到Toolbar有自带的标题,这是因为我们Activity里面调用了 setSupportActionBar(mToolBar);这句代码。

当我们 setSupportActionBar(mToolBar); 而又没有指定标题的时候,那么标题就是程序名。

三、上吧,五兄弟

我们之前说过,ToolBar可以包含

  • 导航按钮(类似向上按钮) (A navigation button)
  • logo图片 (A branded logo image.)
  • 标题和子标题 (A title and subtitle)
  • 一个或者多个自定义view (One or more custom views.)
  • 菜单。 (An action menu.)

那么现在我们来添加一下
先加三个:
导航按钮(类似向上按钮) (A navigation button)
logo图片 (A branded logo image.)
标题和子标题 (A title and subtitle)

        mToolBar.setTitle("Title");
        setSupportActionBar(mToolBar);

        mToolBar.setNavigationIcon(R.mipmap.nac_icon);
        mToolBar.setLogo(R.mipmap.sugar);
        mToolBar.setSubtitle("SubTit");

导航按钮,logo图片,没什么提别的,
但是加标题的时候,mToolBar.setTitle("Title");必须在setSupportActionBar(mToolBar);之前设置标题才会生效

  • 一个或者多个自定义view

ToolBar继承自ViewGroup,所以是个容器,可以放置View

Paste_Image.png

.
.

自定义View放置在ToolBar里面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="com.am.toolbartest.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/mToolBar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        >

        <TextView
            android:id="@+id/mTvDiy"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="DIY"
            android:textColor="#fff"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            />
    </android.support.v7.widget.Toolbar>
</RelativeLayout>
  • 菜单

在menu下创建菜单文件,(如果menu文件夹不在则创建之)

Paste_Image.png

代码

<?xml version="1.0" encoding="utf-8"?>
<menu 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"
    tools:context=".MainActivity" >
    <item android:id="@+id/action_ball"
        android:title="篮球"
        android:orderInCategory="80"
        android:icon="@mipmap/ball_icon"
        app:showAsAction="ifRoom" />
    <item android:id="@+id/action_tip"
        android:title="提醒"
        android:orderInCategory="90"
        android:icon="@mipmap/bell_icon"
        app:showAsAction="ifRoom" />

    <item android:id="@+id/action_menu"
        android:title="设置"
        android:orderInCategory="90"
        android:icon="@mipmap/menu_icon"
        app:showAsAction="ifRoom" />
</menu>

showAsAction的值

app中有一个菜单(menu),showAsAction主要是针对这个菜单的显示起作用的,它有三个可选项:

always:总是显示在界面上
never:不显示在界面上,只让出现在右边的三个点中
ifRoom:如果有位置才显示,不然就出现在右边的三个点中

.
.
创建关联菜单

    // 创建关联菜单
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main,menu);
        return true;
    }

.
.
菜单的点击回调

    // 菜单的点击回调
    private Toolbar.OnMenuItemClickListener onMenuItemClick = new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem menuItem) {
            String msg = "";
            switch (menuItem.getItemId()) {
                case R.id.action_ball:
                    msg += "Click ball";
                    break;
                case R.id.action_tip:
                    msg += "Click action_tip";
                    break;
                case R.id.action_menu:
                    msg += "Click setting";
                    break;
            }
            if(!msg.equals("")) {
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
            return true;
        }
    };

.
.
设置菜单点击监听
mToolBar.setOnMenuItemClickListener(onMenuItemClick);

综上,完整的MainActivity代码如下:

public class MainActivity extends AppCompatActivity {
    private Toolbar mToolBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolBar = (Toolbar) findViewById(R.id.mToolBar);
        mToolBar.setTitle("Title");
        setSupportActionBar(mToolBar);

        mToolBar.setNavigationIcon(R.mipmap.nac_icon);
        mToolBar.setLogo(R.mipmap.sugar);
        mToolBar.setSubtitle("SubTit");
        // 设置菜单点击监听
        mToolBar.setOnMenuItemClickListener(onMenuItemClick);
    }

    // 菜单的点击回调
    private Toolbar.OnMenuItemClickListener onMenuItemClick = new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem menuItem) {
            String msg = "";
            switch (menuItem.getItemId()) {
                case R.id.action_ball:
                    msg += "Click ball";
                    break;
                case R.id.action_tip:
                    msg += "Click action_tip";
                    break;
                case R.id.action_menu:
                    msg += "Click setting";
                    break;
            }
            if(!msg.equals("")) {
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
            return true;
        }
    };


    // 创建关联菜单
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main,menu);
        return true;
    }
}

.
.
效果图:

Paste_Image.png

如果菜单项特别多,那么会在菜单的最右边一向形成列表

<?xml version="1.0" encoding="utf-8"?>
<menu 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"
    tools:context=".MainActivity" >
    <item android:id="@+id/action_ball"
        android:title="篮球"
        android:orderInCategory="80"
        android:icon="@mipmap/ball_icon"
        app:showAsAction="ifRoom" />
    <item android:id="@+id/action_tip"
        android:title="提醒"
        android:orderInCategory="90"
        android:icon="@mipmap/bell_icon"
        app:showAsAction="ifRoom" />

    <item android:id="@+id/action_menu"
        android:title="设置"
        android:orderInCategory="90"
        android:icon="@mipmap/menu_icon"
        app:showAsAction="ifRoom" />

    <item
        android:title="其他1"
        android:orderInCategory="90"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="ifRoom" />

    <item
        android:title="其他2"
        android:orderInCategory="90"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="ifRoom" />

    <item
        android:title="其他3"
        android:orderInCategory="90"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="ifRoom" />
</menu>

gif

较多.gif

Action Menu Item文本颜色

如果想要修改Menu Item的文本颜色,可以这么做

1、style Theme指定文本颜色、

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textColorPrimary">#968e48</item> <!--指定颜色-->
    </style>

2、toolbar所在的xml文件指定我们自己的主题

    <!--app:popupTheme="@style/AppTheme" 指定主题-->
    <android.support.v7.widget.Toolbar
        android:id="@+id/mToolBar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/AppTheme"  
        >

当item图标较多,在Toolbar无法容下item,那么这时候Toolbar会在menu的最右边生成一个菜单图标(三个竖直排列的小点),有兴趣可以改变menu文件尝试一下。上面的代码的我们自己也弄了一个一个竖直的三个小图的菜单图标,两者不是同一个东西,需要区分一下。

四、回退带主页

ToolBar可以生成一个回退按钮,按下就回退到主页

1、在清单文件对应的activity添加对应的meta-data,键值的性质,指定主页。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.am.toolbartest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".IndexActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SecondActivity"/>

        <activity android:name=".MainActivity">
            <!-- Parent activity meta-data to support 4.0 and lower -->
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".IndexActivity" />
        </activity>
    </application>

</manifest>

.
.
2、MainActivity设定setDisplayHomeAsUpEnabled(true);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolBar = (Toolbar) findViewById(R.id.mToolBar);
        mToolBar.setTitle("Title");
        setSupportActionBar(mToolBar);

        mToolBar.setNavigationIcon(R.mipmap.nac_icon);
        mToolBar.setLogo(R.mipmap.sugar);
        mToolBar.setSubtitle("SubTit");
        // 设置菜单点击监听
        mToolBar.setOnMenuItemClickListener(onMenuItemClick);

        // Get a support ActionBar corresponding to this toolbar
        ActionBar ab = getSupportActionBar();

        // Enable the Up button
        ab.setDisplayHomeAsUpEnabled(true);
    }

返回主页效果图

返回主页.gif

如果只想回退到上一页

mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onBackPressed();
            }
        });

五、 Action View

利用Action View,可以更好利用ToolBar的空间,比如ToolBar上面有一个搜索按钮,平时是一个图片,搜索时就变成一个 搜索栏 。

搜索.gif

在Toolbar/Actionbar中添加SearchView实现搜索功能

Action Views 和 Ation Providers

六、Action Provider

Action Views 和 Ation Providers

七、DrawerLayout + NavigationView + Toolbar

概念熟悉之 DrawerLayout

Paste_Image.png

赶紧翻一翻 DrawerLayout Google文档

DrawerLayout acts as a top-level container for window content that allows for interactive "drawer" views to be pulled out from one or both vertical edges of the window.

Drawer positioning and layout is controlled using the android:layout_gravity attribute on child views corresponding to which side of the view you want the drawer to emerge from: left or right (or start/end on platform versions that support layout direction.) Note that you can only have one drawer view for each vertical edge of the window. If your layout configures more than one drawer view per vertical edge of the window, an exception will be thrown at runtime.


To use a DrawerLayout, position your primary content view as the first child with width and height of match_parent and no layout_gravity>. Add drawers as child views after the main content view and set the layout_gravity appropriately. Drawers commonly use match_parent for height with a fixed width.

DrawerLayout.DrawerListener can be used to monitor the state and motion of drawer views. Avoid performing expensive operations such as layout during animation as it can cause stuttering; try to perform expensive operations during the STATE_IDLE state. DrawerLayout.SimpleDrawerListener offers default/no-op implementations of each callback method.

DrawerLayout.DrawerListener这个接口可用来抽屉的开闭状态和运动趋势。


As per the Android Design guide, any drawers positioned to the left/start should always contain content for navigating around the application, whereas any drawers positioned to the right/end should always contain actions to take on the current content. This preserves the same navigation left, actions right structure present in the Action Bar and elsewhere.

For more information about how to use DrawerLayout, read Creating a Navigation Drawer.

Drawer是“抽屉”的意思。

  • DrawerLayout 是作为一个页面(视窗)的顶层容器,它允许可以从页面(视窗)的边缘拉出。
  • 抽屉的子View通过android:layout_gravity属性可以决定抽取的抽取方向,一般是向左或者向右,(如果平台版本支持的话还可以上下抽出)。需要注意的是,每个页面的抽屉只能有一个抽出方向,如果你配置了多个抽出方向,那么抛异常。
  • 使用DrawerLayout的时候,第一个子View可以作为在 主内容 View,主内容View高度一般为match_parent并且不设置layout_gravity,然后,我们需要在 主内容 View后面添加一个View作为 抽屉 View ,抽屉View可以通过layout_gravity属性设置一个合适的抽出方向。抽屉View通常高度是match_parent ,而宽度是固定的。
  • NavigationView通常是作为DrawerLayout的子View和DrawerLayout配套使用的。

等等,NavigationView 又是什么??

概念熟悉之 NavigationView

NavigationView

Paste_Image.png

Google说:

Represents a standard navigation menu for application. The menu contents can be populated by a menu resource file.

NavigationView is typically placed inside a DrawerLayout.
  • NavigationView是一个标准的android程序的导航菜单。菜单的内容由xml布局文件进行填充。
  • NavigationView通常是放置在DrawerLayout的内部。

大概两者就是这么合作的

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fitsSystemWindows="true">

     <!-- Your contents -->

     <android.support.design.widget.NavigationView
         android:id="@+id/navigation"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_gravity="start"
         app:menu="@menu/my_navigation_items" />
 </android.support.v4.widget.DrawerLayout>

来代码

1、配置布局文件

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!--Coordinator 协调  做伸缩-->
    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> 

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> 
        </android.support.design.widget.AppBarLayout>
        <FrameLayout
            android:id="@+id/frame_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/appbar"
            android:scrollbars="none"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    </android.support.design.widget.CoordinatorLayout>

    <!--导航菜单  设置 头部 和 菜单-->
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer"
        app:headerLayout="@layout/nav_header"
        />

</android.support.v4.widget.DrawerLayout>

这里面都没什么特殊的,要注意的只是

        app:menu="@menu/drawer"
        app:headerLayout="@layout/nav_header"

这两行代码。

顾名思义,一个是菜单,menu,一个是头部布局,headerLayout

  • menu 必须,文件在menu文件夹配置

  • headerLayout 非必须,视需而定

  • 另外NavigationView layout_gravity这个属性系统好像不会自动提示,需要手动敲上去

.
.
menu文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/navigation_person"
            android:icon="@mipmap/edit"
            android:title="个人设置" />
        <item
            android:id="@+id/navigation_item_intimity"
            android:icon="@mipmap/setting"
            android:title="隐私设置" />
        <item
            android:id="@+id/navigation_item_system"
            android:icon="@mipmap/share"
            android:title="系统设置 " />

        <item
            android:id="@+id/navigation_item_about"
            android:icon="@mipmap/sugar"
            android:title="关于" />
    </group>
</menu>

.
.
headerLayout nav_header

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="?attr/colorPrimaryDark"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="16dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">


    <ImageView
        android:id="@+id/profile_image"
        android:layout_width="72dp"
        android:layout_height="72dp"
        android:layout_marginTop="20dp"
        android:src="@mipmap/ic_launcher"
        />
    <TextView
        android:layout_marginTop="10dp"
        android:textSize="18sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="APP DEV"
        android:gravity="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
        />

</LinearLayout>

2、Activity

public class DrawerLayoutActivity  extends AppCompatActivity{

    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private Toolbar mToolbar;

    private NavigationView mNavigationView;

    private static final int ANIM_DURATION_TOOLBAR = 300;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drawer);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.open,
                R.string.close);
        mDrawerToggle.syncState();
        mDrawerLayout.addDrawerListener(mDrawerToggle); // 给抽屉布局添加 导航 监听
        
        // 导航部分开始
        mNavigationView = (NavigationView) findViewById(R.id.navigation_view);

        // ====  导航头
        View headerView1 = mNavigationView.getHeaderView(0);
        ImageView profileView = (ImageView) headerView1.findViewById(R.id.profile_image);
        if (profileView != null) {
            profileView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    switchToSystem();
                    mDrawerLayout.closeDrawers();
                    mNavigationView.getMenu().getItem(1).setChecked(true);
                }
            });
        }// ====  导航头
        
        // 导航菜单
        mNavigationView.setNavigationItemSelectedListener(
                new NavigationView.OnNavigationItemSelectedListener() {
                    @Override
                    public boolean onNavigationItemSelected(MenuItem menuItem) {
                        switch (menuItem.getItemId()) {
                            case R.id.navigation_person:
                                switchToPerson();
                                break;
                            case R.id.navigation_item_intimity:
                                switchToIntimity();
                                break;
                            case R.id.navigation_item_system:
                                switchToSystem();
                                break;
                            case R.id.navigation_item_about:
                                switchToAbout();
                                break;

                        }
                        menuItem.setChecked(true);
                        mDrawerLayout.closeDrawers();
                        return true;
                    }
                });

        // 导航部分结束

        switchToPerson();
    }


    private void switchToPerson() {
        getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, new PersonFragment()).commit();
        mToolbar.setTitle("个人设置~");
    }

    private void switchToIntimity() {
        getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, new IntimityFragment()).commit();
        mToolbar.setTitle("隐私设置~~");
    }

    private void switchToSystem() {
        getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, new SystemFragment()).commit();
        mToolbar.setTitle("系统设置~~~");
    }
    private void switchToAbout() {
        getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, new AboutFragment()).commit();
        mToolbar.setTitle("关于~~~~");
    }

}

3、fragment参考

PersonFragment

public class PersonFragment extends Fragment {

    private View rootView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_person,null);
        return rootView;
    }
}

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:text="个人设置"
        android:layout_centerInParent="true"
        />

</RelativeLayout>

效果展示:

抽屉导航.gif

本篇完。

MD系列1、RecyclerView良好参考
Md系列3、CoordinatorLayout 里 Toobar和TabLayout等发生的一系列故事

demo参考

参考:

更简单更全的material design状态栏

JuheNews系列之二 · ToolBar + AppBarLayout + CoordinatorLayout

ToolBar与AppcompatAcitivity实现浸入式Statusbar效果

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,350评论 0 17
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,394评论 2 45
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,391评论 25 707
  • 原文地址:http://www.android100.org/html/201606/06/241682.html...
    AFinalStone阅读 906评论 0 1
  • 最近没故事(买不买书) 我想了好久,脑子突然就冒出了一个这样的题目,的确,如题,我最近没有什么故事可写,所以很无...
    阿驴阅读 236评论 0 1