作者:李旺成
時(shí)間:2016年4月22日
接上篇:AndroidStudyDemo之Android6.x新控件介紹(一)
四、TabLayout
先看效果:
簡介
TabLayout 就是用來做選項(xiàng)卡切換這一類效果的控件,在兼容包中提供。對于 Tab 的實(shí)現(xiàn) Google 上提供過不少方案,先有 TabHost;然后在 Android 3.x 上又出現(xiàn)了 ActionBar 提供的 Tab;現(xiàn)在有了更好的實(shí)現(xiàn),那就是使用用 TabLayout。
當(dāng)然,還有非常多的各種第三方開源庫來實(shí)現(xiàn) Tab,例如:JakeWharton 大神開源的組件 ViewPagerIndicator 相信很多人都用過。
- Tabs 選項(xiàng)卡,效果類似網(wǎng)易新聞客戶端的 Tab
- Google 官方實(shí)現(xiàn)的 TabPageIndicator
先看看官方的介紹:
先看繼承結(jié)構(gòu)(習(xí)慣從繼承結(jié)構(gòu)來學(xué)習(xí)和分析如何使用新控件),和 TabPageIndicator 一樣繼承自 HorizontalScrollView,這個(gè)很好理解,Tab 的數(shù)量一多,那就需要橫向滑動,直接繼承自 HorizontalScrollView 來實(shí)現(xiàn)會省事很多(不會偷懶的程序員不是好程序員,呵呵,不記得誰說的了,不發(fā)表個(gè)人意見)。
對于控件還需要關(guān)注的一點(diǎn)就是它的屬性(在 Layout 中使用的),那么來看看官方對 TabLayout 的特有屬性的介紹:
坑!竟然沒有對 TabLayout 特有屬性的介紹,那只能先看看它提供的方法了:
好像也沒有太多可參考的,那直接用起來。
簡單使用
1、導(dǎo)入兼容包
compile 'com.android.support:design:23.3.0'
2、直接使用示例
TabLayout 繼承自 HorizontalScrollView,那先當(dāng)作 HorizontalScrollView 試試:
在 Layout 中簡單使用,沒有使用 TabLayout 特有的屬性:
<android.support.design.widget.TabLayout
android:id="@+id/tl_test"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
在 Java 代碼中使用:
private void addTab() {
mTabsNum += 1;
TabLayout.Tab tab = mTestTL.newTab().setText("TAB" + mTabsNum);
mTestTL.addTab(tab);
}
private void removeFirstTab() {
int count = mTestTL.getTabCount();
if (count <= 0) return;
mTestTL.removeTabAt(0);
}
private void removeLastTab() {
int count = mTestTL.getTabCount();
if (count <= 0) return;
mTestTL.removeTabAt(count - 1);
}
private void removeAllTabs() {
int count = mTestTL.getTabCount();
if (count <= 0) return;
mTabsNum = 0;
mTestTL.removeAllTabs();
}
上面示例代碼演示了 Tab 的添加和刪除,簡單介紹下 Tab 類和 addTab() 方法:
- Tab 類:這是 TabLayout 中的靜態(tài)內(nèi)部類,看下源碼,
構(gòu)造方法是 private 的,不能直接 new 對象,注釋中提示可以使用 TabLayout 的 newTab() 方法來創(chuàng)建實(shí)例。
- addTab() 方法:addTab() 有四個(gè)重載方法,那就看參數(shù)最多的那個(gè)吧!(參數(shù)最多的都會用了,其他的就很簡單了)
第一個(gè)參數(shù) tab,就是 Tab 類的實(shí)例;第二個(gè)參數(shù) position,用于指定加入的 Tab 需要插入的位置,這里需注意,調(diào)用該方法之前最好通過 getTabCount() 方法獲取當(dāng)前 TabLayout 中所擁有的 Tab 總數(shù),如果 position + 1 大于總 TabLayout 中的 Tab 總數(shù)會導(dǎo)致數(shù)組越界(這個(gè)應(yīng)該不難理解);第三個(gè)參數(shù) setSelected,用于指定新加入的 Tab 是否為選中狀態(tài)。
3、配合 ViewPager 使用
TabLayout 是個(gè)指示器,確切的說是 ViewPager 的指示器,所以更常見的使用場景是配合 ViewPager 來使用。
在 Layout 中使用:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.diygreen.android6new.newwidget2.TabLayoutDemo3Activity">
<android.support.design.widget.TabLayout
android:id="@+id/tl_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"/>
<android.support.v4.view.ViewPager
android:id="@+id/vp_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/tl_bottom"
android:scrollbars="none" />
</RelativeLayout>
將把 TabLayout 當(dāng)作普通的布局使用即可。
在 Java 代碼中:
private void initData() {
int size = mTitleArr.length;
mViewList = new ArrayList<>(size);
// 添加 Tab,初始化 View 列表
for (int i = 0; i < size; i++) {
mTitleTL.addTab(mTitleTL.newTab().setText(mTitleArr[i]));
View view = LayoutInflater.from(this).inflate(R.layout.item_tablayoutdemo2_vp, null);
TextView tv = (TextView) view.findViewById(R.id.tv_text);
tv.setText(mTitleArr[i]);
mViewList.add(view);
}
mAdapter = new TabLayoutDemo2PagerAdapter(mViewList);
// 填充 ViewPager
mContentVP.setAdapter(mAdapter);
// 給ViewPager添加監(jiān)聽
mContentVP.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTitleTL));
// 設(shè)置setOnTabSelectedListener
mTitleTL.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
// 切換到指定的 item
mContentVP.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
要實(shí)現(xiàn) TabLayout 與 ViewPager 的聯(lián)動,有兩個(gè)關(guān)鍵方法:
// 給 ViewPager 添加頁面改變監(jiān)聽
addOnPageChangeListener()
// 設(shè)置 Tab 選擇監(jiān)聽
setOnTabSelectedListener()
上面代碼中都做了示例,使用也很簡單。
說明:還有另一種方式來實(shí)現(xiàn)聯(lián)動,使用的是 setupWithViewPager() 方法
// 設(shè)置 TabLayout 與 ViewPager 聯(lián)動
setupWithViewPager():該方法在 TabLayoutDemo4Activity.java 中使用了,會在下面做說明。
4、實(shí)現(xiàn)底部 Tab
這個(gè)很簡單,直接看布局文件就可以了。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.diygreen.android6new.newwidget2.TabLayoutDemo3Activity">
<android.support.design.widget.TabLayout
android:id="@+id/tl_bottom"
style="@style/DIYTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
<android.support.v4.view.ViewPager
android:id="@+id/vp_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/tl_bottom"
android:scrollbars="none" />
</RelativeLayout>
-_-^,把 TabLayout 放到 ViewPager 下面即可...
5、自定義 TabLayout 樣式
TabLayout 的特有屬性:
看著好像不少,但仔細(xì)看一下,其實(shí)不多,而且這些屬性名稱大部分應(yīng)該都認(rèn)識,或者說在其他控件中使用過。
沒有文檔說明,那就看著效果來簡單解釋下這些屬性,還是那句話先用起來。
效果如圖:
首先,在 style 文件中定義:
<!-- 自定義 TabLayout 樣式 -->
<style name="DIY.TabLayout" parent="Widget.Design.TabLayout">
<item name="paddingEnd">10dp</item>
<item name="paddingStart">10dp</item>
<item name="tabBackground">@color/colorPrimaryDark</item>
<item name="tabContentStart">10dp</item>
<item name="tabGravity">center</item>
<item name="tabIndicatorColor">#999900</item>
<item name="tabIndicatorHeight">6dp</item>
<item name="tabMaxWidth">@dimen/tab_max_width</item>
<item name="tabMinWidth">@dimen/tab_min_width</item>
<item name="tabMode">scrollable</item>
<item name="tabPaddingBottom">2dp</item>
<item name="tabPaddingEnd">10dp</item>
<item name="tabPaddingStart">10dp</item>
<item name="tabPaddingTop">15dp</item>
<item name="tabSelectedTextColor">#ffcc00</item>
<item name="tabTextAppearance">@style/DIY.TabTextAppearance</item>
<item name="tabTextColor">#000066</item>
</style>
<!-- 自定義 TabText 的外觀 -->
<style name="DIY.TabTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#006600</item>
<item name="textAllCaps">false</item>
</style>
然后,在 Layout 中使用樣式
<android.support.design.widget.TabLayout
android:id="@+id/tl_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/DIY.TabLayout"/>
有幾個(gè)屬性要解釋一下:
- tabGravity:用來設(shè)置 TabLayout 的布局方式,只有兩個(gè)可選值fill 和 center,默認(rèn)值是 fill
- tabIndicatorColor:用來設(shè)置底部指示器的顏色
- tabIndicatorHeight:用來設(shè)置底部指示器的高度
- tabMode:用來設(shè)置 TabLayout 的布局模式,有兩個(gè)取值
fixed:固定不可滾動
scrollable: 可滾動的
對應(yīng)的 Java 方法:
- setTabGravity()
- setSelectedTabIndicatorColor()
- setSelectedTabIndicatorHeight()
- setTabMode():MODE_FIXED 或 MODE_SCROLLABLE
其他的屬性都是用于設(shè)置 Tab 中文本的屬性,這基本上可以參考 TextView。
6、給 TabLayout 加角標(biāo)
其實(shí)就是利用 TabLayout.Tab 的 setCustomView() 方法,最好自己維護(hù)好為 Tab 設(shè)置的 CustomView 列表,以便更新數(shù)據(jù)。
簡單的示例:
private void initData() {
int size = mTitleArr.length;
mTabItemViewList = new ArrayList<>(size);
mViewPagerViewList = new ArrayList<>(size);
// 添加 Tab,初始化 View 列表
for (int i = 0; i < size; i++) {
View tabView = LayoutInflater.from(this).inflate(R.layout.item_tablayout_item, null);
TextView tabViewTV = (TextView) tabView.findViewById(R.id.tv_tab);
tabViewTV.setText(mTitleArr[i]);
mTabItemViewList.add(tabView);
View vpView = LayoutInflater.from(this).inflate(R.layout.item_tablayoutdemo2_vp, null);
TextView viViewTV = (TextView) vpView.findViewById(R.id.tv_text);
viViewTV.setText(mTitleArr[i] + i);
mViewPagerViewList.add(vpView);
}
mAdapter = new TabLayoutDemo2PagerAdapter(mViewPagerViewList);
// 填充 ViewPager
mContentVP.setAdapter(mAdapter);
mTitleTL.setupWithViewPager(mContentVP);
size = mTitleTL.getTabCount();
for (int i = 0; i < size; i++) {
TabLayout.Tab tab = mTitleTL.getTabAt(i);
if (tab != null) {
tab.setCustomView(mTabItemViewList.get(i));
}
}
mContentVP.setCurrentItem(1);
}
注意事項(xiàng)
1、關(guān)于 TabMode
如果你發(fā)現(xiàn)你的 TabLayout 不能滾動,那么可能是沒有設(shè)置 TabMode 為 MODE_SCROLLABLE 的緣故
2、關(guān)于 remove 方法
TabLayout 的 removeXxx 方法沒有什么問題,這里要說的是當(dāng) TabLayout 與 ViewPager 一起使用的時(shí)候,ViewPager 不能同步刷新的問題。設(shè)想一下你在刪除 Tab 的同時(shí)希望刪除該 Tab 下 ViewPager 中的相應(yīng)頁面,這時(shí)你修改 ViewPager 的數(shù)據(jù)源,然后調(diào)用 ViewPager Adapter 的 notifyDataSetChanged()(ListView 中是這個(gè)思路,并且沒什么問題),你會發(fā)現(xiàn)結(jié)果并不是你料想的那般。
對于該問題,不是一兩句話可以說清楚的,你可以 Google 一下“ViewPager notifyDataSetChanged 無效”,有一大堆文章在討論這個(gè)問題,但是都不能覆蓋所有場景。所以,打算專門寫一篇文章來討論這個(gè)問題。
3、關(guān)于 setupWithViewPager 方法
在設(shè)置 TabLayout 與 ViewPager 聯(lián)動的時(shí)候,有一種方式是,分別調(diào)用 ViewPager 的 addOnPageChangeListener() 方法關(guān)聯(lián) TabLayout,和 TabLayout 的 setOnTabSelectedListener() 方法關(guān)聯(lián) ViewPager;這樣才能達(dá)到聯(lián)動的目的。
還有一種方式是通過 TabLayout 的 setupWithViewPager() 方法,剛開始以為直接調(diào)用該方法即可完成聯(lián)動(就是第一種方式的其他代碼都不動,只是刪除關(guān)聯(lián)用到的兩個(gè)方法)。試了一下,結(jié)果發(fā)現(xiàn) Tab 的文本沒有顯示出來,下面的線條有了,而且可以聯(lián)動。坑!有沒有,我沒打算去分析里面的原因了,直接給出正確的添加 Tab 的方式,注意是調(diào)用 setupWithViewPager() 方法的時(shí)候:
private void initData() {
int size = mTitleArr.length;
mViewList = new ArrayList<>(size);
// 初始化 View 列表
for (int i = 0; i < size; i++) {
View view = LayoutInflater.from(this).inflate(R.layout.item_tablayoutdemo2_vp, null);
TextView tv = (TextView) view.findViewById(R.id.tv_text);
tv.setText(mTitleArr[i]);
mViewList.add(view);
}
mAdapter = new TabLayoutDemo2PagerAdapter(mViewList);
// 填充 ViewPager
mContentVP.setAdapter(mAdapter);
mTitleTL.setupWithViewPager(mContentVP);
size = mTitleTL.getTabCount();
for (int i = 0; i < size; i++) {
TabLayout.Tab tab = mTitleTL.getTabAt(i);
if (tab != null) {
tab.setText(mTitleArr[i]);
}
}
mContentVP.setCurrentItem(1);
}
4、關(guān)于 setScrollPosition 方法
該方法是用來設(shè)置 Tab 下那條線的位置的,來看下方法簽名:
public void setScrollPosition(int position, float positionOffset, boolean updateSelectedText)
這里想說明的問題是,該方法使用的時(shí)候容易引起誤會,對第二個(gè)參數(shù)不理解。
第一個(gè)參數(shù)表示當(dāng)前 Tab 的位置,第二個(gè)參數(shù)是偏移值,該值的取值范圍是0到1的一個(gè)半開區(qū)間,最后一個(gè)參數(shù)表示是否置移動后位置所對應(yīng)的Tab為選中狀態(tài)。這里要說明的是 positionOffset 這個(gè)參數(shù)是一個(gè)倍數(shù)值,這里不打算分析其實(shí)現(xiàn),有興趣的可以去看看這篇文章TabLayout:另一種Tab的實(shí)現(xiàn)方式,里面解釋得不錯(cuò)。
5、setTabGravity 方法
上面介紹了該方法的作用,要注意的是 setTabGravity 方法只有在 Mode 為 MODE_FIXED 的情況下才有用。
6、setTabTextColors 方法無效?
setTabTextColors 當(dāng)然不是說真的無效,場景是這樣的,如果你在 addTab 方法之后,再來調(diào)用該方法,這時(shí)會看到,該方法沒有起作用(TabLayout 的 Bug 有沒有?)。
當(dāng)然這也不是什么無解的問題,我們完全可以通過使用自定義 View 的來作為 TabLayout 的 Item,那么這個(gè)控制權(quán)就全部在我們手上了。
小結(jié)
TabLayout 的介紹就到這里了,使用比較簡單。
五、NavigationView
先看看效果:
簡介
NavigationView 是兼容包中提供的用來實(shí)現(xiàn)導(dǎo)航菜單界面的新控件,看看該控件的特點(diǎn):
- 導(dǎo)航抽屜,被設(shè)計(jì)用于應(yīng)用導(dǎo)航
- 提供了一種通用的導(dǎo)航方式,體現(xiàn)了設(shè)計(jì)的一致性
- 導(dǎo)航菜單框架,使用menu資源填充數(shù)據(jù)
- 可以更簡單高效的實(shí)現(xiàn)導(dǎo)航菜單
來看下官方介紹:
NavigationView 繼承自 Framelayout,從繼承結(jié)構(gòu)來看,參考意義不大,好在官方給了示例代碼,那了解下它特有的屬性,然后用起來再說。
NavigationView 的特有屬性:
簡單使用
1、導(dǎo)入兼容包
compile 'com.android.support:design:23.3.0'
2、在 Layout 中使用
<?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"
android:id="@+id/dl_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Content -->
<FrameLayout
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/tb_title"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways" />
</FrameLayout>
<!-- Drawer -->
<android.support.design.widget.NavigationView
android:id="@+id/navigation_left"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer_menu"/>
</android.support.v4.widget.DrawerLayout>
3、定義 headerLayout
在上面的 NavigationView 中使用了 app:headerLayout,該屬性不是必須的,這里是為了更完整的演示如何使用。這個(gè) headerLayout 就是一個(gè)自定義的布局,如:
<?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="170dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
android:background="@mipmap/bg_drawer_header">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:id="@+id/iv_headimg"
android:src="@mipmap/ic_logo"
android:layout_above="@+id/switch_online"
android:layout_alignParentStart="true" />
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/switch_online"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_margin="@dimen/activity_horizontal_margin"
android:checked="false" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="DIY-green"
android:id="@+id/tv_name"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
4、定義 menu
NavigationView 的 app:menu 屬性用于指定自定義的菜單布局文件,一般是必選項(xiàng),當(dāng)然也可以在代碼中動態(tài)設(shè)置。這個(gè) 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/drawer_home"
android:checked="true"
android:icon="@mipmap/ic_alarm_add_black"
android:title="Alarm"/>
<item
android:id="@+id/drawer_favourite"
android:icon="@mipmap/ic_cast_connected_black"
android:title="Connected"/>
<!-- 為 Item 添加子菜單,實(shí)現(xiàn)分組 -->
<item
android:id="@+id/section"
android:icon="@mipmap/ic_more_horiz_grey"
android:title="Group">
<menu>
<group
android:checkableBehavior="single">
<item
android:id="@+id/drawer_downloaded"
android:icon="@mipmap/ic_computer_grey"
android:title="Computer"/>
<item
android:id="@+id/drawer_more"
android:icon="@mipmap/ic_border_color_grey"
android:title="Border"/>
</group>
</menu>
</item>
<item
android:id="@+id/drawer_settings"
android:icon="@mipmap/ic_fullscreen_black"
android:title="FullScreen"/>
</group>
</menu>
上面示例代碼中使用了 android:checkableBehavior="single" 屬性,是為了保證該 Group 下的 Item 為單選狀態(tài),這個(gè)會在注意事項(xiàng)里面詳細(xì)介紹。
可以通過為 Item 添加子菜單來實(shí)現(xiàn)帶有頭部的分組效果,注意一下分組的效果,在該分組的最上面會添加一條分隔;還有就是雖然示例代碼中給分組 Item 設(shè)置了 icon 屬性,但是并不會顯示。
5、設(shè)置 Menu Item 的點(diǎn)擊監(jiān)聽
直接使用 NavigationView 的 setNavigationItemSelectedListener() 方法即可:
mLeftNavigation.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override public boolean onNavigationItemSelected(MenuItem menuItem) {
Snackbar.make(mContentView, menuItem.getTitle() + " pressed", Snackbar.LENGTH_LONG).show();
menuItem.setChecked(true);
mRootDL.closeDrawers();
return true;
}
});
NavigationView 的封裝性比較高,使用起來比較簡單,代碼不多,但是有些小細(xì)節(jié)需要注意。
注意事項(xiàng)
將 NavigationView 布局的內(nèi)容延伸到狀態(tài)欄實(shí)實(shí)現(xiàn)
先看下效果:
圖中使用紅線條圈出來的就是將 NavigationView 布局的內(nèi)容延伸到狀態(tài)欄實(shí)的效果。
要實(shí)現(xiàn)該效果,有幾個(gè)要注意的地方:
- android:fitsSystemWindows 屬性
最好將 DrawerLayout 和 NavigationView 的該屬性都設(shè)置為 true - values-v21 中的 style
<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- 該屬性必須 -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:colorControlHighlight">@color/colorPrimary</item>
<item name="android:windowSharedElementsUseOverlay">false</item>
</style>
要實(shí)現(xiàn)上述效果,按照這兩步走就 OK 了。關(guān)于該問題更進(jìn)一步的討論,可以參考知乎上的一個(gè)提問: Android 5.0 如何實(shí)現(xiàn)將布局的內(nèi)容延伸到狀態(tài)欄實(shí)?,在這里就不展開討論了。
有分組時(shí) Item 單選實(shí)現(xiàn)
上面說了,將 Group 中的 android:checkableBehavior 設(shè)置為 "single" 是為了實(shí)現(xiàn)菜單項(xiàng)的單選。
但現(xiàn)在有個(gè)問題,如果在菜單項(xiàng)下面有子菜單,也就是有分組的情況時(shí);如果僅在最外層使用 group 標(biāo)簽,如下
<group
android:checkableBehavior="single">
...
</group>
包裹所有的菜單項(xiàng)和分組的話,是達(dá)不到單選效果的。(這里就不演示了,你可以自行修改示例項(xiàng)目去看看效果)
我的解決方案是將分組的 Item 也用 group 標(biāo)簽包裹,當(dāng)然也得將 checkableBehavior 屬性設(shè)置為 “single”,看代碼:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 最外層使用 group 標(biāo)簽 --->
<group
android:checkableBehavior="single">
<item
android:id="@+id/drawer_home"
android:checked="true"
android:icon="@mipmap/ic_alarm_add_black"
android:title="Alarm"/>
...
<item
android:id="@+id/section"
android:icon="@mipmap/ic_more_horiz_grey"
android:title="Group">
<menu>
<!-- 在分組中使用 group 標(biāo)簽 --->
<group
android:checkableBehavior="single">
<item
android:id="@+id/drawer_downloaded"
android:icon="@mipmap/ic_computer_grey"
android:title="Computer"/>
<item
android:id="@+id/drawer_more"
android:icon="@mipmap/ic_border_color_grey"
android:title="Border"/>
</group>
</menu>
</item>
...
</group>
</menu>
NavigationView 配合 DrawerLayout 來實(shí)現(xiàn)側(cè)滑菜單是不錯(cuò)的選擇,更關(guān)鍵的是這些都是 Google 官方提供的控件,兼容性方面會好點(diǎn)。
小結(jié)
本來打算只用兩篇來介紹 Android 6.x 中的新控件的,但是考慮到有不少控件都是 MaterialDesign 中的比較重要的成員,所以,會稍微介紹詳細(xì)點(diǎn)。
Android 6.x 的新控件介紹還有一篇,這將是 Android 6.x 系列介紹的最后一篇了。
未完待續(xù)...
項(xiàng)目地址
附件
參考
TabLayout:另一種Tab的實(shí)現(xiàn)方式
使用Desgin包組件 TabLayout助你輕松打造網(wǎng)易搜狐頂部導(dǎo)航欄
Material Design之NavigationView和DrawerLayout實(shí)現(xiàn)側(cè)滑菜單欄
使用TabLayout實(shí)現(xiàn)底部Tab布局
android design library提供的TabLayout的用法
Android Design Support Library初探,NavigationView實(shí)踐
Android 5.0 如何實(shí)現(xiàn)將布局的內(nèi)容延伸到狀態(tài)欄實(shí)?
Design Support Library (I): Navigation View的使用