读第一行代码第12章-2.滑动菜单

在之前介绍过Toolbar的基础之上,现在介绍滑动菜单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"
tools:context=".MainActivity">

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.DrawerLayout>  

现在一个简易的滑动菜单已经制作好了,但是用户怎么知道我们有滑动菜单这个功能呢?
所以我们就需要在标题栏的最左边加入一个导航按钮,点击按钮也会显示滑动菜单,所以我们需要导入一张导航图片到drawable-xxhdpi目录下。然后修改MainActivity中的代码:

public class MainActivity extends AppCompatActivity {

private DrawerLayout mDrawerLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mDrawerLayout = findViewById(R.id.drawer_layout);
    ActionBar actionBar = getSupportActionBar();
    if(actionBar != null){
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeAsUpIndicator(R.drawable.navigate);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.toolbar,menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);
            break;
        case R.id.Share:
            Toast.makeText(this,"You click Share!",Toast.LENGTH_SHORT).show();
            break;
        case R.id.Upload:
            Toast.makeText(this,"You click Upload!",Toast.LENGTH_SHORT).show();
            break;
        case R.id.Add:
            Toast.makeText(this,"You click Add!",Toast.LENGTH_SHORT).show();
            break;
        case R.id.Delete:
            Toast.makeText(this,"You click Delete!",Toast.LENGTH_SHORT).show();
            break;
        case R.id.Setting:
            Toast.makeText(this,"You click Setting!",Toast.LENGTH_SHORT).show();
            break;
        default:break;
    }
    return true;
}
}  

通过比较不难发现,其实我们就是在昨天的基础之上加了这几行代码:

private DrawerLayout mDrawerLayout;


mDrawerLayout = findViewById(R.id.drawer_layout);
    ActionBar actionBar = getSupportActionBar();
    if(actionBar != null){
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeAsUpIndicator(R.drawable.navigate);
    }


case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);
            break;  

上面首先调用findViewById()方法得到了DrawerLayout的实例,然后调用getSupportActionBar()方法得到了ActionBar的实例,再调用setDisplayHomeAsUpEnabled()方法让导航栏显示出来,然后通过setHomeAsUpIndicator()方法为导航栏设置一个图片。
接下来通过对HomeAsUp的点击事件(HomeAsUp按钮的id永远是android.R.id.home),然后调用openDrawer()方法将滑动菜单展示出来。如图:

此时导航图标已经显示出来了,但是滑动菜单还是空的,所以我们需要加点东西进去,首先导入下面两个库:

implementation 'com.android.support:design:27.1.1'
implementation 'de.hdodenhof:circleimageview:2.2.0'  

第一行的是Design Support库,第二行是开源的CircleImageView,他可以轻松的实现图片圆形化的功能。
在添加之前,我们还需要准备两个东西:menu和headLayoout,把Navigation分成上下两部分,menu用来显示下面具体的菜单项,headLayout用来显示上面的头布局。
先来准备menu,我事先找了五张图片作为按钮的图标,将他们放在drawable-xxhdpi目录下。然后右击 menu文件夹→NEW→Menu→Menu resource file,创建一个nav_menu.xml文件,修改代码如下:

<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_call"
        android:icon="@drawable/nav_call"
        android:title="Call"/>
    <item
        android:id="@+id/nav_friends"
        android:icon="@drawable/nav_friends"
        android:title="Friends"/>
    <item
        android:id="@+id/nav_location"
        android:icon="@drawable/nav_location"
        android:title="Location"/>
    <item
        android:id="@+id/nav_mail"
        android:icon="@drawable/nav_mail"
        android:title="Mail"/>
    <item
        android:id="@+id/nav_task"
        android:icon="@drawable/nav_task"
        android:title="Task"/>
</group>
</menu>  

我们首先在

中嵌套了一个标签,然后将group的checkableBehavior属性指定为single。其中group表示一组,checkableBehavior指定为single表示组中的所有菜单项都是单选。

接下来准备头布局headLayout,这是一个可以随意定制的布局,我们将在这里放置头像、用户名、邮箱这三项内容。所以我们还得准备一张图片作为头像,仍然把他放在drawable-xxhdpi目录下,然后右击layout文件夹→NEW→Layout resource file,创建一个nav_header.xml文件,修改其中的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="180dp"
android:padding="10dp"
android:background="?attr/colorPrimary">

<de.hdodenhof.circleimageview.CircleImageView
    android:id="@+id/image"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:src="@drawable/robot"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/username"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginStart="8dp"
    android:text="Joker"
    android:textColor="#FFF"
    android:textSize="14sp"
    app:layout_constraintBottom_toTopOf="@+id/mail"
    app:layout_constraintStart_toStartOf="parent" />

<TextView
    android:id="@+id/mail"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginStart="8dp"
    android:text="123456@gmail.com"
    android:textColor="#FFF"
    android:textSize="14sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>  

这个布局很简单,把头像居中,然后把用户名和邮箱都放在左下角。
之后我们再次修改activity_main中的代码,在里面添加NavigationView控件,如下:

<?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"
tools:context=".MainActivity">

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

<android.support.design.widget.NavigationView
    android:id="@+id/view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:menu="@menu/nav_menu"
    app:headerLayout="@layout/nav_header">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>  

这样我们的布局就完成了,然后修改MainActivity中的代码:

package com.project.software.toolbar;

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.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private DrawerLayout mDrawerLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mDrawerLayout = findViewById(R.id.drawer_layout);
    NavigationView navView = findViewById(R.id.view);
    ActionBar actionBar = getSupportActionBar();
    if(actionBar != null){
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeAsUpIndicator(R.drawable.navigate);
    }
    navView.setCheckedItem(R.id.nav_call);
    navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            mDrawerLayout.closeDrawers();
            return true;
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.toolbar,menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);
            break;
        case R.id.Share:
            Toast.makeText(this,"You click Share!",Toast.LENGTH_SHORT).show();
            break;
        case R.id.Upload:
            Toast.makeText(this,"You click Upload!",Toast.LENGTH_SHORT).show();
            break;
        case R.id.Add:
            Toast.makeText(this,"You click Add!",Toast.LENGTH_SHORT).show();
            break;
        case R.id.Delete:
            Toast.makeText(this,"You click Delete!",Toast.LENGTH_SHORT).show();
            break;
        case R.id.Setting:
            Toast.makeText(this,"You click Setting!",Toast.LENGTH_SHORT).show();
            break;
        default:break;
    }
    return true;
}
} 

通过观察不难发现,里面就多添加了以下几行代码:

NavigationView navView = findViewById(R.id.view);  


navView.setCheckedItem(R.id.nav_call);
    navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            mDrawerLayout.closeDrawers();
            return true;
        }
    });  

其中,通过findViewById()的方法获取到NavigationView的实例,然后通过setCheckedItem()方法将Call菜单设置成默认选中,接着通过setNavigationItemSelectedListener()监听菜单选中事件,在这里可以添加选中的逻辑事件,然后调用closeDrawers()方法关闭滑动菜单。如图:

Over

posted @ 2018-06-14 08:35  干翻苍穹  阅读(311)  评论(0编辑  收藏  举报