Android 使用Material Design实现滑动菜单


  • 前言
  • DrawerLayout布局
  • NavigationView控件


前言

  Android Material Design库提供了统一的UI设计和个性化界面风格,这其中,侧边滑动菜单可谓是一大亮点,Material Design提供了DrawerLayout布局和NavigationView控件实现了这一特性,两者珠联璧合,使开发者能够轻松的实现比较酷炫的滑动菜单效果。本文是对《Android第一行代码》第十二章的学习记录,以及滑动菜单的实现的总结。

DrawerLayout布局

  DrawerLayout是Design库中实现滑动菜单效果的支撑性布局,它允许放入两个直接子控件,第一个子控件是主屏幕中的内容,第二个子控件是滑动菜单中显示的内容。我们在activity_main.xml文件中使用DrawerLayout布局如下:


<androidx.drawerlayout.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">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

    <TextView
        android:layout_gravity="start"
        android:text="This is menu"
        android:textSize="30sp"
        android:background="#FFF"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
androidx.drawerlayout.widget.DrawerLayout>

  实现效果如下:
Android 使用Material Design实现滑动菜单_第1张图片
  我们在标题栏添加一个侧边栏按钮,这样可以使得滑动菜单更加人性化,修改MainActivity.java代码如下:

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);
        // 获取DrawerLayout布局
        mDrawerLayout = findViewById(R.id.drawer_layout);
        ActionBar actionBar = getSupportActionBar();
        if(actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
        }
    }

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

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch(item.getItemId()){
            case android.R.id.home:
                mDrawerLayout.openDrawer(GravityCompat.START);
                break;
            case R.id.backup:
                Toast.makeText(this,"You clicked Backup!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(this,"You clicked Delete!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.settings:
                Toast.makeText(this,"You clicked Settings", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }
}

  首先用findViewId方法获取DrawerLayout的实例,然后用getSupportActionBar方法获取了ActionBar的实例,在这里ActionBar是由Toolbar来充当,然后调用了ActionBar方法的setDisplayHomeAsUpEnabled方法和setHomeAsUpIndicator方法让导航按钮显示出来并设置对应的图标。实际上,Toolbar左侧的按钮叫做HomeAsup按钮

  然后在onOptionsItemSelected方法中对HomeAsup点击事件进行处理,HomeAsup按钮的值永远是android.R.id.home,然后openDrawer方法将滑动菜单显示出来,具体效果如下:
Android 使用Material Design实现滑动菜单_第2张图片

  显然,这个滑动菜单比较原始而低级,我们下面通过NavigationView控件来美化我们的滑动菜单。

NavigationView控件

  NavigationView是Design Support中提供的一个控件,它不仅严格按照Material Design要求进行设计,还可以将滑动菜单变得非常简单。我们简单了解一下NavigationView的用法——

首先,在build.gradle文件的dependencies添加依赖——

dependencies {
    ...
    implementation 'com.android.support:design:28.0.0-alpha3'
    implementation 'de.hdodenhof:circleimageview:2.1.0'
    ...
}

  其中,第二行是CircleImageView第三方库,它能够轻松实现图片圆形化

  然后,为了方便显示菜单优化效果,我们添加一个menu文件nav_menu.xml负责显示菜单栏部分,内容如下:


<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:icon="@drawable/ic_call"
        android:title="Call"
        android:id="@+id/nav_call"/>

    <item
        android:icon="@drawable/ic_friends"
        android:title="Friends"
        android:id="@+id/nav_friends"/>

    <item
        android:id="@+id/nav_mail"
        android:title="Mail"
        android:icon="@drawable/ic_mail"/>

    <item
        android:icon="@drawable/ic_task"
        android:title="Task"
        android:id="@+id/nav_task" />
group>
menu>

  同时,添加对应的图标文件。

  然后再添加头像布局文件nav_header.xml,负责优化头像区域 ,内容如下:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:padding="10dp"
    android:background="?attr/colorPrimary">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/icon_image"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@drawable/ic_header"
        android:layout_centerInParent="true"/>

    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="[email protected]"
        android:textSize="14sp"
        android:textColor="#FFF"/>

    <TextView
        android:id="@+id/mail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/username"
        android:text="Jason"
        android:textSize="14sp"
        android:textColor="#FFF"/>

RelativeLayout>

  其中,CircleImageView是用来将头像圆形化。然后在activity_main.xml文件中修改NavigationView区域的代码:


<androidx.drawerlayout.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">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_gravity="start"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/nav_header"/>
androidx.drawerlayout.widget.DrawerLayout>

  可以看到,在NavigationView中,分别有一个menu和headerLayout,即刚才设置的菜单栏和头像区域

  对应的,修改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);
        NavigationView navView = findViewById(R.id.nav_view);
        ActionBar actionBar = getSupportActionBar();
        if(actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
        }
        navView.setCheckedItem(R.id.nav_call);
        navView.setNavigationItemSelectedListener((v)->{
            mDrawerLayout.closeDrawers();
            return true;
        });
    }

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

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch(item.getItemId()){
            case android.R.id.home:
                mDrawerLayout.openDrawer(GravityCompat.START);
                break;
            case R.id.backup:
                Toast.makeText(this,"You clicked Backup!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(this,"You clicked Delete!", Toast.LENGTH_SHORT).show();
                break;
            case R.id.settings:
                Toast.makeText(this,"You clicked Settings", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }
}

  最终实现效果如下:
Android 使用Material Design实现滑动菜单_第3张图片

  可以看到,相比于之前的滑动菜单界面,已经变得比较美观了。

你可能感兴趣的:(Android)