滑動選單DrawerLayout詳解(實時更新,未完待續...)
前言:目前所寫程式碼都是參照第一行程式碼所寫,但日後專案發現新的應用一定會實時更新。
一,在佈局中引入DrawerLayout
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="@+id/myFirstDrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
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="#1EB9FD"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</FrameLayout >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="滑動有驚喜"
android:layout_gravity="start"
android:background="#1EB9FD"/>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
這段程式碼還加入了toolbar,不熟悉可以點我上篇博文,我們來解釋其它部分。我在DrawerLayout內部還加了一個簡單的textView,裡面最重要的一點是layout_gravity屬性,它決定了drawerLayout從哪一邊劃出來。
二,在activity中引入DrawerLayout
先貼整體程式碼
MainActivity.class
package com.example.slidingmenu;
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.MenuItem;
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);//用toolbar替代acitonbar
ActionBar actionBar=getSupportActionBar();
if(actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true);//讓導航按鈕顯示
actionBar.setHomeAsUpIndicator(R.mipmap.navigation);//用自己定義的導航欄圖示代替預設的箭頭圖示
}
mDrawerLayout=(DrawerLayout)findViewById(R.id.myFirstDrawerLayout);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home://HomeAsUp按鈕預設固定的名稱
mDrawerLayout.openDrawer(GravityCompat.START);//傳入你在layout_gravity所填值,我這裡是填了start
}
return true;
}
}
注意這裡的onOptionsItemSelected方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home://HomeAsUp按鈕預設固定的名稱
mDrawerLayout.openDrawer(GravityCompat.START);//傳入你在layout_gravity所填值,我這裡是填了start
}
return true;
}
這個是為了實現點選導航按鈕,選單從側面滑出的功能。android.R.id.home是HomeAsUp(即圖中那個圖片按鈕)的預設固定名稱。接著我們向openDrawerf方法中傳入gravity型別引數,注意這裡必須傳入你在佈局檔案中一致的屬性。因為我在activty_main.xml檔案中填的是layout_gravity:”start”,所以這裡保持一致。
這樣我們已經實現了一個最簡單的滑動選單。
當然我們可以自定以佈局,豐富其中的內容,讓它如qq那樣美觀,不過google的大神們已經幫我們鋪好了路。使用NavigationView控制元件可以輕鬆實現qq側滑選單。
三,利用NavigationView定製漂亮的側滑選單
A,新增依賴庫
NavigatonView是Design Support庫所提供,所以我們要在app/build.gradle中引入依賴庫:
compile "com.android.support:design:25.3.1"
compile 'de.hdodenhof:circleimageview:2.1.0'
第一行依賴庫就是Design Support,注意sdk版本問題,如果是24則填:24.2.1;25則填:25.3.1;26則填:26.0.2,這些在google官網都可以查到的。第二行依賴庫是一個將任何形狀圖片變為圓形圖片的一個開源庫。
B ,定義menu和headerlayout檔案
NavigationView的使用需要menu和headerlayout兩個佈局檔案,headerlayout即是我們qq的上半部分,通常用來放頭像,menu既是下半部分,提供一些選項。
首先在res中建立menu資料夾,再在menu資料夾中新建menu.xml
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/setting"
android:icon="@mipmap/setting_item"
android:title="Setting"/>
<item
android:id="@+id/telephone"
android:icon="@mipmap/call_item"
android:title="Telephone"/>
</group>
</menu>
其中checkableBehavior=”single”代表item為單選,title代表item的內容。
再在layout資料夾中新建headerlayout.xml
headlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:padding="10dp"
android:orientation="vertical"
android:background="#1EB9FD">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/headPortrait"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/head_portrait"
android:layout_centerInParent="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="吃著冰淇凌望著藍天"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
這個很簡單,放入頭像圖片和一段文字。
C,在佈局中引入NavigationView
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="@+id/myFirstDrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
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="#1EB9FD"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/mFirstNavigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/menu"
app:headerLayout="@layout/headlayout"/>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
其中menu和headerlayout分別對應我們之前建立的兩個佈局檔案。
D,可以在activity中為NavigationView的item新增點選事件
MainActivity.class
package com.example.slidingmenu;
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.MenuItem;
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);//用toolbar替代acitonbar
ActionBar actionBar=getSupportActionBar();
if(actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true);//讓導航按鈕顯示
actionBar.setHomeAsUpIndicator(R.mipmap.navigation);//用自己定義的導航欄圖示代替預設的箭頭圖示
}
mDrawerLayout=(DrawerLayout)findViewById(R.id.myFirstDrawerLayout);
NavigationView mNavigationView=(NavigationView)findViewById(R.id.mFirstNavigationView);
mNavigationView.setCheckedItem(R.id.setting);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener(){
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mDrawerLayout.closeDrawers();//關閉側滑選單
return true;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home://HomeAsUp按鈕預設固定的名稱
mDrawerLayout.openDrawer(GravityCompat.START);//傳入你在layout_gravity所填值,我這裡是填了start
}
return true;
}
}
主要看如下程式碼
mNavigationView.setCheckedItem(R.id.setting);
設定預設選中的item。
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener(){
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mDrawerLayout.closeDrawers();//關閉側滑選單
return true;
}
});
為每個item新增監聽,點選Item後關閉側滑選單,這部分可以類比button等控制元件點選事件來理解。
E,為NavigationView的headerLayout新增點選事件
很奇怪官方為什麼不寫個headerLayout監聽事件的封裝,但即使這樣我們還是有辦法做到。
下面是一種可行的方法:
MainActivity.class
View headerLayout=mNavigationView.inflateHeaderView(R.layout.headlayout);
CircleImageView headPortrait=(CircleImageView)headerLayout.findViewById(R.id.headPortrait);
headPortrait.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
Toast.makeText(MainActivity.this, "你點選了頭像", Toast.LENGTH_SHORT).show();
}
});
注意這樣寫,headerLayout會載入兩遍,因為其中的inflate方法。所以要在activity_main.xml先去除headerlayout:
app:headerlayout="@layout/headlayout"
還有另一種方法,不用去除,只需把`
View headerLayout=mNavigationView.inflateHeaderView(R.layout.headlayout);
換成
View headerLayout=mNavigationView.getHeaderView(0);
經過以上步驟相信大家都能做出一個漂亮的側滑選單。