版權(quán)聲明:本作品采用知識(shí)共享署名-相同方式共享 4.0 國(guó)際許可協(xié)議進(jìn)行許可。
轉(zhuǎn)載或引用前請(qǐng)注明來(lái)自踏雪cc 侵權(quán)必究。
Android抽屜式導(dǎo)航隧甚,也就是側(cè)滑菜單,大家對(duì)這種設(shè)計(jì)一定都不陌生了,現(xiàn)在很多應(yīng)用使用了抽屜式導(dǎo)航,最常見(jiàn)的就是QQ。
本文通過(guò)一個(gè)示例來(lái)演示怎么使用Google支持庫(kù)提供的DrawerLayout實(shí)現(xiàn)抽屜式導(dǎo)航峭判。對(duì)什么時(shí)候該使用這種設(shè)計(jì)給出一些建議开缎。
- 在谷歌推出DrawerLayout之前,經(jīng)常使用的是SlidingMenu來(lái)實(shí)現(xiàn)側(cè)滑林螃。
- Google I/O 2013在Android Support Library添加了DrawerLayout奕删,實(shí)現(xiàn)側(cè)滑菜單效果,支持向下兼容
- API文檔
https://developer.android.google.cn/training/implementing-navigation/nav-drawer.html - 設(shè)計(jì)指南
https://material.google.com/patterns/navigation-drawer.html
示例
gradle配置:
dependencies {
compile 'com.android.support:appcompat-v7:25.0.0'
}
布局
抽屜式導(dǎo)航欄疗认,包含兩部分視圖完残,一部分用來(lái)顯示屏幕主內(nèi)容,一部分顯示導(dǎo)航欄横漏,導(dǎo)航欄可以是列表谨设,也可以是其它的組件。
創(chuàng)建activity_drawer.xml缎浇,把DrawerLayout作為布局的根視圖扎拣,content_frame為屏幕主內(nèi)容(運(yùn)行時(shí)以Fragment填充),left_drawer為左側(cè)導(dǎo)航欄素跺。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ListView
android:id="@+id/left_drawer"
android:layout_width="@dimen/drawer_menu_width"
android:layout_height="match_parent"
android:layout_gravity="left"
android:choiceMode="singleChoice"
android:background="@android:color/white"/>
</android.support.v4.widget.DrawerLayout>
注意:
- content_frame必須是第一個(gè)子視圖二蓝,因?yàn)閤ml會(huì)對(duì)布局按層疊順序排序。
- left_drawer必須指定layout_gravity指厌,如果不指定會(huì)有異常刊愚。
- left_drawer的寬度不應(yīng)該超過(guò)320dp,這樣用戶(hù)始終可以看到屏幕主內(nèi)容部分踩验。
填充左側(cè)導(dǎo)航欄
drawer_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp"
tools:text="測(cè)試"/>
在arrays.xml定義字符串?dāng)?shù)組
<string-array name="drawer_menu">
<item>@string/movie</item>
<item>@string/music</item>
<item>@string/book</item>
</string-array>
Activity里獲取字符串?dāng)?shù)組鸥诽,并使用ArrayAdapter填充
private String[] mTitles;
mTitles = getResources().getStringArray(R.array.drawer_menu);
mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.activity_main_list_item, mTitles));
mDrawerList.setOnItemClickListener(this);
OnItemClick里面用Fragment填充主內(nèi)容部分
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
selectItem(position);
}
private void selectItem(int position){
Fragment fragment = new DrawerFragment();
Bundle args = new Bundle();
args.putInt(DrawerFragment.DRAWER_NUMBER, position);
fragment.setArguments(args);
getFragmentManager().beginTransaction()
.replace(R.id.content_frame, fragment, DrawerFragment.TAG)
.commit();
mDrawerList.setItemChecked(position, true);//選中的導(dǎo)航高亮顯示
setTitle(mTitles[position]);//設(shè)置標(biāo)題
mDrawerLayout.closeDrawer(mDrawerList);//關(guān)閉左側(cè)導(dǎo)航欄
}
@Override
public void setTitle(CharSequence title) {
mTitle=title;
getActionBar().setTitle(title);
}
主內(nèi)容部分
DrawerFragment接收DrawerActivity傳遞過(guò)來(lái)的數(shù)據(jù),顯示對(duì)應(yīng)的標(biāo)題
public class DrawerFragment
extends Fragment {
public final static String DRAWER_NUMBER = "number";
public final static String TAG = "DrawerFragment";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_drawer_content, container, false);
int i = getArguments().getInt(DRAWER_NUMBER);
String str = getResources().getStringArray(R.array.drawer_menu)[i];
TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(str);
return view;
}
}
fragment_drawer_content.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/common_padding"
android:textColor="@color/common_text_color"
android:textSize="@dimen/common_text_size"
tools:text="測(cè)試"/>
</LinearLayout>
這時(shí)候就已經(jīng)實(shí)現(xiàn)了DrawerLayout的基本功能了箕憾,可以通過(guò)手勢(shì)打開(kāi)側(cè)邊欄衙传,點(diǎn)擊跳轉(zhuǎn)到對(duì)應(yīng)的內(nèi)容頁(yè)。
監(jiān)聽(tīng)打開(kāi)和關(guān)閉事件
要監(jiān)聽(tīng)導(dǎo)航欄打開(kāi)和關(guān)閉事件厕九,需要在DrawerLayout上調(diào)用setDrawerListener()蓖捶,并向其傳遞DrawerLayout.DrawerListener的實(shí)現(xiàn)。
如果使用了ActionBar扁远,可以擴(kuò)展ActionBarDrawerToggle類(lèi)
private ActionBarDrawerToggle mDrawerToggle;
mDrawerToggle=new ActionBarDrawerToggle(this,
mDrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close){
public void onDrawerClosed(View view){
super.onDrawerClosed(view);
getActionBar().setTitle(mTitle);
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView){
super.onDrawerOpened(drawerView);
getActionBar().setTitle(mTitle);
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
什么時(shí)候該用側(cè)邊欄俊鱼?
雖然現(xiàn)在很多應(yīng)用都使用了側(cè)邊欄的樣式刻像,但是并不是所有的場(chǎng)景都適合側(cè)邊欄局,需要根據(jù)具體場(chǎng)景來(lái)分析并闲。用戶(hù)體驗(yàn)設(shè)計(jì)師們:側(cè)邊抽屜式導(dǎo)航可能會(huì)降低你產(chǎn)品一半的用戶(hù)參與度 這篇文章通過(guò)實(shí)際場(chǎng)景分析了什么情況該使用側(cè)邊欄细睡,不想看的童鞋可以直接看下面的結(jié)論:
如果應(yīng)用主要的功能和內(nèi)容都在一個(gè)頁(yè)面里面。只是一些用戶(hù)設(shè)置和選項(xiàng)需要顯示在其他頁(yè)面里帝火。處于讓主頁(yè)面看上去干凈美觀的目的可以把這些輔助功能放在側(cè)邊欄里溜徙。
而如果你的應(yīng)用有不同的視圖,且他們是平級(jí)的犀填,需要用戶(hù)同等地對(duì)待蠢壹,側(cè)邊欄將會(huì)浪費(fèi)掉大多數(shù)的用戶(hù)對(duì)于側(cè)邊欄中入口的潛在參與度和交互程度。