Android >> 44. Material Design sliding menu

DrawerLayout

It's simple:

<androidx.drawerlayout.widget.DrawerLayout
	android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">
    <FrameLayout
        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"
        tools:context=".MainActivity">

        <androidx.appcompat.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">
        </androidx.appcompat.widget.Toolbar>
    </FrameLayout>

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

DrawerLayout is a layout that allows two direct sub-controls to be placed in the layout. The first sub-control is the content displayed on the home screen, and the second sub-control is the content displayed in the sliding menu.
(Note: The android:layout_gravity property of the second child control is mandatory. Here I specify start, which means that the left or right will be judged according to the system language.)

Add navigation buttons for sliding menus

public class MainActivity extends AppCompatActivity {
    Toolbar toolbar;
    DrawerLayout drawerLayout;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawerLayout = findViewById(R.id.drawer_layout);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null){
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.navigation);
        }
    }
    
	... ...
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
			... ...
            case android.R.id.home:{
                drawerLayout.openDrawer(GravityCompat.START);
                break;
            }
            default:
                break;
        }
        return true;
    }
}

The first step is to retrieve the current Drawer Layout and ActionBar instances separately (although the specific implementation of this ActionBar is done by Toolbar).

Then call the setDisplayHomeAsUpEnabled() method of ActionBar to display the navigation button, and then call the setHomeAsUpIndicator() method to set a navigation button (the left-most button of Toolbar is called the HomeAsUp button, and the default icon is a return arrow, meaning to return to the previous activity). Here we have modified its default style and function.
Next, in the onOptions ItemSelected () method, the click event of the HomeAsUp button is processed (the id of the HomeAsUp button is always android.R.id.home), and then the open Drawer () method of DrawerLayout is called to display the sliding menu.
The openDrawer() method requires that a Gravity parameter be passed in. To ensure that the behavior here is consistent with the definition in XML, we pass in GravityCompat.START.

NavigationView

Navigation View is a control provided in the Design Support library. It is not only designed strictly according to the requirements of Material Design, but also makes the implementation of sliding menu pages very simple.

Since this control is provided in the Design Support library, we need to introduce this library into the project:

implementation 'com.android.support:design:24.2.1'

Here, we come into contact with an open source repository: CircleImageView
It can transform the shape of the picture into a circle, which is very suitable for the scene where the head image needs to be displayed. Therefore, according to its requirements, it needs to introduce a library:

implementation 'de.hdodenhof:circleimageview:3.0.0'

Before using Navigation View, we need to prepare two things: menu and header Layout.

  1. Menu is used to display specific menu items in Navigation View.
  2. Header Layout is used to display the header layout in Navigation View.

Prepare menu

Menu folder New Menu resource file, create a nav_menu.xml file:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/eat"
            android:icon="@drawable/eat"
            android:title="Eat"/>
        <item
            android:id="@+id/bluetooth"
            android:icon="@drawable/bluetooth"
            android:title="Bluetooth"/>
        <item
            android:id="@+id/clock"
            android:icon="@drawable/clock"
            android:title="Clock"/>
        <item
            android:id="@+id/find"
            android:icon="@drawable/find"
            android:title="Find"/>
        <item
            android:id="@+id/location"
            android:icon="@drawable/location"
            android:title="Location"/>
    </group>
</menu>

We nested a < group > tag in the < Menu > tag, and then set the checkable Behavior property of the group to single.
Group represents a group and checkable Behavior is single to indicate that all menu items in the group can only be radio-selected.

Five item s are defined here.

Prepare header Layout

This layout can be customized at will. I only put my head, name and mailbox here.

The layout folder New Layout resource file creates a nav_header.xml file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:background="#81C784">

        <de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/profile_image"
            android:layout_width="96dp"
            android:layout_height="96dp"
            android:layout_centerInParent="true"
            android:src="@mipmap/hacker"
            app:civ_border_color="#FF000000"
            app:civ_border_width="2dp" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/profile_image"
            android:gravity="center">

            <TextView
                android:id="@+id/mailbox_textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:text="11458xxxxx@qq.com"
                android:textColor="#373737"
                android:textSize="14sp" />

            <TextView
                android:id="@+id/username_textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_above="@id/mailbox_textview"
                android:text="Waao"
                android:textColor="#373737"
                android:textSize="14sp" />

        </RelativeLayout>

    </RelativeLayout>
</RelativeLayout>

Assembly Navigation View

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

        <androidx.appcompat.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"></androidx.appcompat.widget.Toolbar>
    </FrameLayout>

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

As you can see, in Navigation View, app:headerLayout and app:menu are set up as just prepared headerLayout and menu, respectively.
(The prefix here is app, because in order to be downward compatible, to prevent low-level Android systems from not having these two attributes)

Handling Click Events

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    drawerLayout = findViewById(R.id.drawer_layout);
    navigationView = findViewById(R.id.nav_view);
    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeAsUpIndicator(R.drawable.navigation);
    }
    navigationView.setCheckedItem(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            drawerLayout.closeDrawers();
            return true;
        }
    });
}

When a click occurs, the sliding menu is closed.

Tags: Android DrawerLayout xml Google

Posted on Sun, 04 Aug 2019 22:36:37 -0700 by philip@hux.co.za