天天看點

仿QQ側滑菜單(二)

仿QQ側滑菜單(二)

        在(一)https://blog.csdn.net/qq_36551426/article/details/80427352中講了一下DrawerLayout的簡單概念,但是這并不足以讓我們去做一個完整的QQ側滑菜單。首先如果隻是簡單的在側面菜單裡出現一些list還好,可以通過listview配合adapter的方式對菜單初始化。但是如果要完成再亂七八糟點的呢?可能我們需要一些新的View了。

        下面我們來看一下NavigationView導航菜單,NavigationView繼承自FrameLayout。一般用于應用的導航菜單,菜單的内容來自于menu檔案。NavigationView通常放置在DrawerLayout内部。

        可能在這裡我們還不是特别清楚這個View的作用是什麼,大家建立工程的時候注意沒有,其實空工程下面是有很多其他類型的模闆工程的,其中一個就有DrawerLayout的模闆。我們打開看看裡面結構是什麼樣的。

仿QQ側滑菜單(二)
仿QQ側滑菜單(二)

        可以看到大體的檔案結構。

仿QQ側滑菜單(二)

        具體的效果,左邊這個就是NavigationView了。這裡分了兩個結構,一個是上面的head,下面是一個menu。我們看一下具體的activity_main.XML:

<?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" />

    <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>      

        這裡很簡單,隻有一個app_bar_main和一個NavigationView。外面是一個DrawerLayout。

        再看一下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"
    tools:context=".MainActivity">

    <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>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" />

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

        一個toolbar,一個content_main,一個FloatingActionButton(懸浮按鈕,在這裡可以忽略)。

        content_main裡面:

<?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="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/app_bar_main">

    <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>      

        隻有一個TextView。到這裡,就可以看清楚整個布局結構了。主界面一個titlebar的xml,下面一個navigationview。然後titlebar裡負責主界面的title之類的東西。而navigationview裡的上下結構怎麼放呢?再來看下面的headerlayout和menu:

仿QQ側滑菜單(二)

        headerlayout的效果,這裡不貼代碼了,看一看結構,一個ImageView,兩個TextView,垂直結構:

仿QQ側滑菜單(二)

            下面是menu的代碼,menu在之前的文章已經講過了https://blog.csdn.net/qq_36551426/article/details/80398403不了解的同學可以再看一下:

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

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_camera"
            android:icon="@drawable/ic_menu_camera"
            android:title="Import" />
        <item
            android:id="@+id/nav_gallery"
            android:icon="@drawable/ic_menu_gallery"
            android:title="Gallery" />
        <item
            android:id="@+id/nav_slideshow"
            android:icon="@drawable/ic_menu_slideshow"
            android:title="Slideshow" />
        <item
            android:id="@+id/nav_manage"
            android:icon="@drawable/ic_menu_manage"
            android:title="Tools" />
    </group>

    <item android:title="Communicate">
        <menu>
            <item
                android:id="@+id/nav_share"
                android:icon="@drawable/ic_menu_share"
                android:title="Share" />
            <item
                android:id="@+id/nav_send"
                android:icon="@drawable/ic_menu_send"
                android:title="Send" />
        </menu>
    </item>

</menu>      

        說白了就是一堆menu,内嵌一堆item。item設定了屬性,id、icon、title。

        OK,總結一下,要做這個效果就是在DrawerLayout裡面加NavigationView,然後NavigationView裡放兩個布局,一個head,一個menu。這樣側滑菜單欄就出現了,而主菜單又是另外一個部分,我們目前大可以不管。

//---------------------------------------下面我們建立空工程來做自己的側滑效果-----------------------------------------

        首先分析一下,一個側滑菜單,用到DrawerLayout,然後上面有我們自己DIY的title,下面先放空白,側滑菜單放在NavigationView裡。NavigationView很自然的幫我們分為了上下(head,menu)兩個部分,上面用來放我們QQ頭像,簽名等資訊。下面是QQ的一些菜單選項如QQ會員,相冊。

        OK,在activity_main.xml裡放好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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/my_drawer_layout"
    tools:context=".MainActivity">

    <android.support.design.widget.NavigationView
        android:id="@+id/Nav_view"
        app:menu="@menu/nav_menu"
        android:layout_gravity="left"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_head"
        android:layout_width="340dp"
        android:layout_height="match_parent"/>

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

        接下來,我們在res檔案夾内建一個menu檔案夾,再建一個nav_menu.xml在裡面,裝上item:

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

    <item
        android:id="@+id/nav_menu_vip"
        android:icon="@drawable/ic_menu_camera"
        android:title="我的QQ會員"
        />
    <item
        android:id="@+id/nav_menu_wallet"
        android:icon="@drawable/ic_menu_camera"
        android:title="QQ錢包"
        />
    <item
        android:id="@+id/nav_menu_zhuangban"
        android:icon="@drawable/ic_menu_camera"
        android:title="個性裝扮"
        />
    <item
        android:id="@+id/nav_menu_shouchang"
        android:icon="@drawable/ic_menu_camera"
        android:title="我的收藏"
        />
    <item
        android:id="@+id/nav_menu_album"
        android:icon="@drawable/ic_menu_camera"
        android:title="我的相冊"
        />
    <item
        android:id="@+id/nav_menu_file"
        android:icon="@drawable/ic_menu_camera"
        android:title="我的檔案"
        />
    <item
        android:id="@+id/nav_menu_liuliang"
        android:icon="@drawable/ic_menu_camera"
        android:title="免流量特權"
        />
</menu>      

        看到這個圖,别慌!

仿QQ側滑菜單(二)

        然後是headlayout,在layout裡建一個nav_head.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:id="@+id/nav_head_view"
    android:background="@drawable/side_nav_bar"
    android:orientation="vertical"
    android:layout_height="180dp">

    <ImageView
        android:id="@+id/head_im"
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:layout_marginLeft="12dp"
        android:layout_marginTop="36dp"
        android:src="@drawable/head" />

    <TextView
        android:text="劉敏敏我愛你劉敏敏我愛你劉敏敏我愛你"
        android:textSize="18sp"
        android:layout_marginLeft="12dp"
        android:layout_marginTop="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>      

        ImageView跟TextView随便放,按自己的效果來。别忘了LinearLayout放背景圖。

仿QQ側滑菜單(二)

        在這裡已經可以有一個側滑菜單欄的效果了,不過我們還可以再進一步,自定義一個Title,裡面放一個Button跟一個TextView。Button響應側滑菜單。這算是模拟QQ主界面點選頭像打開側滑菜單的效果。

        title的代碼跟模闆的一模一樣:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <Button
                android:id="@+id/toolbar_btn"
                android:background="@drawable/ic_menu_manage"
                android:layout_width="50dp"
                android:layout_height="50dp" />

            <TextView
                android:textSize="24sp"
                android:layout_marginLeft="60dp"
                android:text="@string/app_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </android.support.v7.widget.Toolbar>

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

        然後把title放進main.xml裡就可以了。

仿QQ側滑菜單(二)

        OK,在這裡也差不多了,接下來是通過代碼響應一下事件。1、點選button打開關閉側滑菜單欄。2、點選menu内的item響應事件,并關閉菜單。

        我們繼承Navigation.OnNavigationItemSelectedListener,和View.OnClickListener。顧名思義,就是響應item點選事件和button點選事件。

package comr.example.administrator.mydrawertest3;

import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;

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

    private Button button;
    private NavigationView navigationView;
    private DrawerLayout drawerLayout;

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

        drawerLayout = (DrawerLayout)findViewById(R.id.my_drawer_layout);

        button = (Button)findViewById(R.id.toolbar_btn);
        button.setOnClickListener(this);

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

    /**
     * 對navigationview裡的item監聽
     * @param item
     * @return
     */
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.my_drawer_layout);//新變量

        //對于這類點選響應事件,都是對參數getId,因為在底層這些Id都是一串數值,通過數值比較來确定目标
        switch (item.getItemId()){
            //每點選一次菜單中的item就showtoast一次然後将drawerlayout關閉
            case R.id.nav_menu_album:
                showToast("相冊");
                drawer.closeDrawer(Gravity.LEFT);
                break;
            case R.id.nav_menu_file:
                showToast("檔案");
                drawer.closeDrawer(Gravity.LEFT);
                break;
            case R.id.nav_menu_liuliang:
                showToast("流量");
                drawer.closeDrawer(Gravity.LEFT);
                break;
            case R.id.nav_menu_shouchang:
                showToast("收藏");
                drawer.closeDrawer(Gravity.LEFT);
                break;
            case R.id.nav_menu_vip:
                showToast("VIP");
                drawer.closeDrawer(Gravity.LEFT);
                break;
            case R.id.nav_menu_wallet:
                showToast("錢包");
                drawer.closeDrawer(Gravity.LEFT);
                break;
            case R.id.nav_menu_zhuangban:
                showToast("裝扮");
                drawer.closeDrawer(Gravity.LEFT);
                break;
                default:
                    break;
        }

        return true;
    }

    private void showToast(String s) {
        Toast.makeText(this,s,Toast.LENGTH_SHORT).show();
    }

    /**
     * implement clickListener接口,對事件做點選監聽,其實也可以對navigationview裡的item做監聽
     * 但是可以通過implement NavigationView的OnNavigationItemSelectedListener對item做監聽,是以可以分離開
     * @param v
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.toolbar_btn:
                if(drawerLayout.isDrawerOpen(Gravity.LEFT)){ //判斷一下是否已經開啟了,開了關,關了開
                    drawerLayout.closeDrawer(Gravity.LEFT);
                }else drawerLayout.openDrawer(Gravity.LEFT);
                break;
                default:
                    break;
        }
    }
}
      

        不需要多解釋,代碼裡有一些注解,就算不看注解也是很好了解的。

        OK,最後給大家上一張效果圖:

仿QQ側滑菜單(二)

貼一下其他部落格的連結,大家可以參考一下:

https://blog.csdn.net/u012702547/article/details/51253222   Android5.0之NavigationView的使用

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0608/3011.html

Design Support Library (I): Navigation View的使用

https://lvwenhan.com/ios/445.html 再造 “手機QQ” 側滑菜單(一)——實作側滑效果(這個是IOS,不過有更好看的效果,想研究的同學可以稍微看看)

https://blog.csdn.net/lmj623565791/article/details/39257409 Android 高仿 QQ5.0 側滑菜單效果 自定義控件來襲(android版)

Android5.0之NavigationView的使用