Android 記事本8

本篇我們使用 Material Design來實現滑動菜單。

首先在我們的應用程序中添加DrawerLayout依賴:
在這裏插入圖片描述
要在我們的程序中使用DrawerLayout,首先我們的使用DrawerLayout爲頂層佈局,該佈局內一般有兩個組件,第一個一般是FrameLayout顯示屏幕中央內容,第二個是我們的的滑動菜單內容。比如我們今天要修改的NoteListFragment。按照上面的格式我們新的佈局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/drawer_layout_list">

    <androidx.constraintlayout.widget.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="match_parent"
        tools:context=".fragment.NoteListFragment">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/note_recycle_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_note_list_empty"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/note_list_empty"
            android:visibility="gone"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:text="this is a menu drawer"
        android:background="#FFF"/>
</androidx.drawerlayout.widget.DrawerLayout>


那麼android又是如何來判斷DrawerLayout內的組件哪個是我們的滑動菜單呢?

這裏我們需要說明一下那就是android會通過android:layout_gravity屬性進行判斷。官方文檔說明有第一個組件不要設置該屬性,第二個組件設置對應的屬性即可,如上例。
在這裏插入圖片描述
如果兩個組件都設置了同樣的android:layout_gravity,如下所示:

<androidx.constraintlayout.widget.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="match_parent"
        android:layout_gravity="start"
        tools:context=".fragment.NoteListFragment">

    </androidx.constraintlayout.widget.ConstraintLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#FFF"
        android:text="this is a menu drawer" />

在這裏插入圖片描述
也就是說我們需要設置不同的android:layout_gravity屬性即可。比如我們一個left,一個right:
在這裏插入圖片描述
在這裏插入圖片描述
通常我們只需要一個滑動菜單,所以第一個一般使用FragmentLayout用來顯示我們的內容頁面。

當然了,只是在佈局文件中設置是沒有上圖中那個home的圖標的,這裏還需要在代碼中進行設置一下。修改NoteListFragment的initFragmentView方法,追加下面的代碼:

		ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_note_home);
        }

setDisplayHomeAsUpEnabled用來設置顯示左上角圖標,setHomeAsUpIndicator用來指定自定義的圖標。

如果我們要響應該菜單的選擇事件,那麼記得這個的id一定是android.R.id.home:

public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                drawerLayout.openDrawer(GravityCompat.START);
                return true;

            case R.id.menu_note_create:
                Intent intent = new Intent(getActivity(), NoteCreateActivity.class);
                startActivityForResult(intent, 2);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

讓我們看一張效果圖:
在這裏插入圖片描述
這個樣子得菜單似乎比我們的漂亮多了,幸運的是在android中我們可以通過NavigationView來實現相應的效果。

首先我們的導入依賴庫:
在這裏插入圖片描述
在這裏插入圖片描述
接下來我們使用NavigationView替換上面的TextView:

<com.google.android.material.navigation.NavigationView
        android:id="@+id/navigation"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

此時我們的菜單還什麼都沒有。
在這裏插入圖片描述
接下來我們需要利用 app:headerLayout和 app:menu屬性設置header和menu。

創建佈局文件drawer_header.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
    android:background="@drawable/drawer_background"
    android:padding="20dp">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/img_note_logo"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@drawable/logo"
        app:civ_border_color="@color/colorPrimary"
        app:civ_border_width="1dp"
        app:layout_constraintBottom_toTopOf="@id/tv_note_app_name"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_note_app_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="@string/app_name"
        android:textColor="@color/colorPrimary"
        android:textSize="18sp"
        app:layout_constraintBottom_toTopOf="@id/tv_note_introduce"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/img_note_logo" />


    <TextView
        android:id="@+id/tv_note_introduce"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:text="@string/app_introduce"
        android:textColor="@color/colorPrimary"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_note_app_name" />
</androidx.constraintlayout.widget.ConstraintLayout>

指定app:headerLayout爲我們剛創建的佈局文件:

app:headerLayout="@layout/drawer_header"

在這裏插入圖片描述
剩下就是添加我們的menu了。

<?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/menu_home"
            android:icon="@drawable/ic_menu_note_home"
            android:title="@string/note_home" />

        <item
            android:id="@+id/menu_settings"
            android:icon="@drawable/ic_menu_note_settings"
            android:title="@string/note_settings" />

        <item
            android:id="@+id/menu_about"
            android:icon="@drawable/ic_menu_note_about"
            android:title="@string/note_about" />
        <item
            android:id="@+id/menu_feedback"
            android:icon="@drawable/ic_menu_note_feedback"
            android:title="@string/note_feedback" />
    </group>
</menu>

同樣別忘記設置app:menu屬性:

app:menu="@menu/menu_drawer"

在這裏插入圖片描述
同樣的,如果想爲這些菜單添加點擊事件,那麼我們需要實現下面的方法:

    @Override
    protected void initFragmentListener() {
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                Log.d(TAG, "onNavigationItemSelected: " + item.getTitle());
                return false;
            }
        });
    }

在這裏插入圖片描述

當然了,如果還需要處理header處的事件,可以使用getHeaderView(0)方法獲取根view,然後通過findViewById方法獲取到內部的控件進行設置。

 ImageView imageView = navigationView.getHeaderView(0).findViewById(R.id.img_note_logo);
        TextView textView = navigationView.getHeaderView(0).findViewById(R.id.tv_note_app_name);

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "onClick: imageview");
            }
        });

        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "onClick: textview");
            }
        });

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章