Material Design系列风格控件之(二)----NavigationView和DrawerLayout实现侧滑菜单栏

一、简介


DrawerLayout可以轻松的实现抽屉效果、在DrawerLayout中,第一个子View必须是显示内容的view,第二个view是抽屉view,设置属性layout_gravity=”left|right”,表示是从左边滑出还是右边滑出。 


NavigationView是Android M中提出一个新的MD风格的组件,它将自己一分为二,上面显示一个通用的布局,下面显示一组菜单。与DrawerLayout一起使用可以实现通用的侧滑菜单。


简单来说就是:


DrawerLayout:实现侧滑菜单的基础。
NavigationView:作为侧滑菜单布局的一种实现方式。


二、NavigationView占满全屏


DrawerLayout有两个子布局

第一个是主界面(使用FrameLayout,宽高都match_parent)
第二个就是侧滑菜单的布局了(使用NavigationView,通过设置layout_gravity为left 或是right 来确定菜单摆放的位置)。


打开抽屉: DrawerLayout .openDrawer();
关闭抽屉:DrawerLayout.closeDrawer( );



1、布局


目录结构:



NavigationView通常放置在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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <!--第一个,显示的布局-->
    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <!--第二个,不显示的抽屉布局-->
    <!-- 菜单布局NavigationView headerLayout设置HeaderView menu设置菜单 -->
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

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


NavigationView有两个app属性,分别为app:headerLayout和app:menu,headerLayout用于显示头部的布局(可选),menu用于建立MenuItem选项的菜单。


其中:

android:fitsSystemWindows的值用于设置状态栏透明化与否。
android:layout_gravity可设置抽屉,也就是NavigationView从左边或是右边打开。
app:menu用于设置菜单内容的xml布局。
app:headerLayout用于设置NavigationView的HeaderView的xml布局文件。


app_bar_main布局文件为:


<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    >

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>


    <!--引入content_main布局-->
    <include layout="@layout/content_main" />

</android.support.design.widget.CoordinatorLayout>



content_main布局文件为:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_main">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
    <Button
        android:id="@+id/snackbar"
        android:layout_below="@id/textView"
        android:text="点我吧"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</RelativeLayout>


2、编写NavigationView中的menu的xml文件


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

    <group android:checkableBehavior="none">
        <item
            android:id="@+id/nav_me"
            android:title="我"
            android:icon="@mipmap/ic_mine_gray_24"/>
        <item
            android:id="@+id/nav_friend"
            android:title="好友"
            android:icon="@mipmap/ic_friends_gray_24"/>
        <item
            android:id="@+id/nav_notification"
            android:title="通知"
            android:icon="@mipmap/ic_notification_gray_24"/>
        <item
            android:id="@+id/nav_message"
            android:title="私信"
            android:icon="@mipmap/ic_messages_gray_24"
            />
    </group>
    <group android:checkableBehavior="none"
        android:id="@+id/group_manage">
        <item
            android:id="@+id/nav_manage"
            android:title="应用管理"
            android:icon="@mipmap/ic_app_management_gray_24"/>
    </group>
   <group
       android:checkableBehavior="none"
       android:id="@+id/group_settings">
       <item android:id="@+id/nav_theme"
           android:title="主题风格"/>
       <item android:id="@+id/nav_night"
           android:title="夜间模式"/>
       <item android:id="@+id/nav_setting"
           android:title="设置"/>
       <item android:id="@+id/nav_suggestion"
           android:title="意见反馈"/>
       <item android:id="@+id/nav_about"
           android:title="关于"/>

   </group>
</menu>


menu可以分组,group的android:checkableBehavior属性设置为single可以设置该组为单选


Activity主题必须设置先这两个属性


 <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

未设置Activity主题会爆出错误信息:


vCaused by: java.lang.IllegalStateException: This Activity 
already has an action bar supplied by the window decor. 
Do not request Window.FEATURE_SUPPORT_ACTION_BAR 
and set windowActionBar to false in your theme to use a Toolbar instead.

在AndroidManifest.xml中设置主题为android:theme="@style/AppTheme.NoActionBar"


3、实现onNavigationItemSelected接口来处理抽屉菜单项的选中事件。


这里用了ButterKnife所以要加入依赖:

compile 'com.jakewharton:butterknife:7.0.1'

代码如下:

package com.example.demo2;

import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, View.OnClickListener{

    private TextView mTextView;
    private ImageView mImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        mTextView = (TextView) findViewById(R.id.textView);
        mImageView = (ImageView) navigationView.getHeaderView(0).findViewById(R.id.ivAvatar);
        mImageView.setOnClickListener(this);

        ButterKnife.bind(this);

    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View view) {
        if(view.getId()==R.id.ivAvatar){
            Toast.makeText(getApplicationContext(), "点击了头像", Toast.LENGTH_SHORT).show();
            //Intent intent = new Intent(this,LoginActivity.class);
            //startActivity(intent);
        }
    }

    @OnClick(R.id.snackbar)
    void goToSnackbar(){
        //startActivity(new Intent(this,SnackBarActivity.class));
        Toast.makeText(getApplicationContext(), "你点击了我!!!", Toast.LENGTH_SHORT).show();

    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        int id = item.getItemId();
        String string = null;
        switch (id){
            case R.id.nav_me:
                string = "我";
                break;
            case R.id.nav_about:
                string = "关于";
                break;
            case R.id.nav_friend:
                string = "好友";
                break;
            case R.id.nav_manage:
                string = "通知";
                break;
            case R.id.nav_message:
                string = "私信";
                break;
            case R.id.nav_night:
                string = "夜间模式";
                break;
            case R.id.nav_notification:
                string = "通知";
                break;
            case R.id.nav_setting:
                string= "设置";
                break;
            case R.id.nav_suggestion:
                string = "意见反馈";
                break;
            case R.id.nav_theme:
                string = "主题风格";
                break;
        }
        if (!TextUtils.isEmpty(string))
            mTextView.setText("你点击了"+string);
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;

    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //右角设置布局
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

效果图:





示例:http://download.csdn.net/detail/u011781521/9829159


四、NavigationView在Toolbar下方


activity_main.xml布局文件如下:

<?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"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context="zhj.newtoolbardemo.MainActivity">

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

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!-- 内容部分 -->
        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
        <!-- 左侧侧滑部分 -->
        <android.support.design.widget.NavigationView
            android:id="@+id/nv_menu_left"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="left"

            app:headerLayout="@layout/header"
            app:menu="@menu/menu_drawer"/>

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


头文件header.xml:


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

    <ImageView
        android:id="@+id/header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginTop="15dp"
        android:layout_marginBottom="15dp"
        android:background="@mipmap/ic_launcher"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/header"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="15dp"
        android:layout_marginTop="10dp"
        android:text="fendo"
        android:textColor="@android:color/white"
        android:textSize="16sp"/>
</RelativeLayout>


菜单选项文件:


1.menu_drawer.xml


<?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <group>
            <item
                android:id="@+id/navigation_item1"
                android:checkable="true"
                android:checked="true"
                android:icon="@mipmap/ic_launcher"
                android:title="选项一"/>
            <item
                android:id="@+id/navigation_item2"
                android:checkable="true"
                android:icon="@mipmap/ic_launcher"
                android:title="选项二"/>
            <item
                android:id="@+id/navigation_item3"
                android:checkable="true"
                android:icon="@mipmap/ic_launcher"
                android:title="选项三"/>
        </group>
        <item
            android:id="@+id/navigation_sub"
            android:title="设置">
            <menu>
                <item
                    android:id="@+id/navigation_sub_item1"
                    android:checkable="true"
                    android:icon="@mipmap/ic_launcher"
                    android:title="简介"/>
                <item
                    android:id="@+id/navigation_sub_item2"
                    android:checkable="true"
                    android:icon="@mipmap/ic_launcher"
                    android:title="详情"/>
                <item
                    android:id="@+id/navigation_sub_item3"
                    android:checkable="true"
                    android:icon="@mipmap/ic_launcher"
                    android:title="更多"/>
            </menu>
        </item>
    </menu>

2.menu_main.xml

<?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"
 >
    <item android:id="@+id/action_1"
        android:title="其他"
        android:orderInCategory="80"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never" />
    <item android:id="@+id/action_tip"
        android:title="提醒"
        android:orderInCategory="90"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never" />

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

</menu>

Main文件:

package zhj.newtoolbardemo;

import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private DrawerLayout mDrawerLayout;
    private Toolbar mToolBar;
    private ActionBarDrawerToggle mDrawerToggle;
    private NavigationView nv_menu_left;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        mToolBar = (Toolbar) findViewById(R.id.mToolBar);
        nv_menu_left= (NavigationView) findViewById(R.id.nv_menu_left);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);

        View  headerView = nv_menu_left.getHeaderView(0);
        ImageView iv= (ImageView) headerView.findViewById(R.id.header);

        mToolBar.setTitle("标题");  //设置主标题
        setSupportActionBar(mToolBar); //设置actionbar


        getSupportActionBar().setHomeButtonEnabled(true);  //设置返回键可用

        getSupportActionBar().setDisplayHomeAsUpEnabled(true); //创建返回键,并实现打开关/闭监听

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolBar, R.string.app_name, R.string.app_name){
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
            }
            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
            }
        };
        mDrawerToggle.syncState();  //初始化状态

        mDrawerLayout.addDrawerListener(mDrawerToggle); //将DrawerLayout与DrawerToggle绑定

        //为头像设置点击事件
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getApplicationContext(), "你点击了头像", Toast.LENGTH_SHORT).show();
            }
        });

        //设置导航栏NavigationView的点击事件
        nv_menu_left.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem item) {
                Toast.makeText(getApplicationContext(), item.getItemId(), Toast.LENGTH_SHORT).show();
                switch (item.getItemId()) {
                    case R.id.navigation_item1:
                        mToolBar.setTitle("选项一");
                        break;
                    case R.id.navigation_item2:
                        mToolBar.setTitle("选项二");
                        break;
                    case R.id.navigation_item3:
                        mToolBar.setTitle("选项三");
                        break;
                    case R.id.navigation_sub_item1:
                        mToolBar.setTitle("简介");
                        break;
                    case R.id.navigation_sub_item2:
                        mToolBar.setTitle("详情");
                        break;
                    case R.id.navigation_sub_item3:
                        mToolBar.setTitle("更多");
                        break;
                }

                //将选中设为点击状态
                item.setChecked(true);
                //关闭抽屉
                mDrawerLayout.closeDrawers();
                return true;
            }
        });
    }

    // 菜单的点击回调
    private Toolbar.OnMenuItemClickListener onMenuItemClick = new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem menuItem) {
            String msg = "";
            switch (menuItem.getItemId()) {
                case R.id.action_1:
                    msg += "点击其他1";

                    break;
                case R.id.action_tip:
                    msg += "点击提醒";
                    break;
                case R.id.action_menu:
                    msg += "点击设置";
                    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;
    }
}

效果如下:





示例:http://download.csdn.net/detail/u011781521/9829158

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值