材料設(shè)計(jì)是 google 官方在 2014 年谷歌大會(huì)上提出的界面設(shè)計(jì)規(guī)范,力求通過(guò)對(duì)光效、表面質(zhì)感低匙、運(yùn)動(dòng)感的控制旷痕,來(lái)提升安卓界面交互體驗(yàn)。
雖然 Material Design 已經(jīng)推出了三年顽冶,但是實(shí)際應(yīng)用上欺抗,Toolbar 和 TabLayout 是使用最廣泛的。由于需求强重,這段時(shí)間特意提取了 TabLayout 的代碼绞呈,對(duì)于許多只需要 Tablayout 的需求,其實(shí)不需要把整個(gè) Design 包導(dǎo)入间景,還能減小體積佃声。
一、起因
項(xiàng)目現(xiàn)在用的是 HorizontalScrollView + ImageButton + ListView 的方式展示數(shù)據(jù)倘要,根據(jù)點(diǎn)擊來(lái)決定 ListView 顯示的數(shù)據(jù)圾亏。但是由于代碼陳舊,里面的弱標(biāo)志又太多封拧,所以希望能重構(gòu)一下代碼志鹃,讓它的可讀性更高一些,順便優(yōu)化一下交互泽西。
二曹铃、起步
有了需求,需要先寫個(gè) demo 填坑捧杉。去年的時(shí)候 TabLayout + ViewPager + PtrListView 顯示數(shù)據(jù)我是做過(guò)的陕见,因此沒有什么難度。但是到了工程里還是有了一些問題味抖。這里記錄一下评甜。
三、問題
- 1.使用 TabLayout 一直有資源不能找到非竿,或者編譯后就報(bào)錯(cuò)( 有點(diǎn)尷尬蜕着,復(fù)現(xiàn)不出來(lái)了 )
需要使用向后兼容的 AppCompatTheme 和 AppCompatActivity。如果工程的 BaseActivity 是 Activity 的子類红柱,BaseTheme 也不是 AppCompatTheme 的子類,并且因?yàn)橐恍┨厥獾脑虿荒芨膭?dòng)的話蓖乘,可以在清單文件中注冊(cè)頁(yè)面時(shí)锤悄,在 TabActivity 下添加一條屬性:android:theme="@style/Theme.AppCompat.Light.NoActionBar"
- 2.自定義 TabLayout 中的 TabView 時(shí),CusView 中的 ImageView 在第一次進(jìn)入頁(yè)面的時(shí)候嘉抒,不會(huì)變?yōu)?select 狀態(tài)
項(xiàng)目里我查看了 22.0.2 版本的源碼零聚,發(fā)現(xiàn)在 TabLayout.setSelectedTabView() 中并沒有對(duì) CusView 做 select 狀態(tài)的修改。換一種方式,如果直接放入 Icon隶症,發(fā)現(xiàn)除了第一次進(jìn)入政模,后面的部分都是有正常的狀態(tài)改變的。然而修改選中狀態(tài)的方法的權(quán)限卻不是公有蚂会,只能通過(guò)反射獲取淋样。或者胁住,你可以通過(guò) viewpager.setCurrentItem(1),viewpager.setCurrentItem(0),來(lái)達(dá)到目的趁猴。反正我是這么做的。= =
- 3.項(xiàng)目中需要 TabLayout 的 indicator比 TabView 短一些
不同版本的 Design 包彪见,對(duì)于 SlidingTabStrip 的繪制方法不同儡司,主要看當(dāng)前版本下 SlidingTabStrip.setIndicatorPosition 和 SlidingTabStrip.onDraw 方法。onDraw 方法在 25.3.1 不知道為什么改名成 draw 方法了余指。如果需要修改這個(gè)效果請(qǐng)關(guān)注上面兩個(gè)方法中對(duì)應(yīng) left 和 right 的值捕犬。如果是使用 25.3.1 的版本,不妨使用我上面的鏈接酵镜,屬性等等都已經(jīng)修改好了碉碉。
四、使用
Design 包的更新速度還算可以笋婿,但是每個(gè)包總是會(huì)改動(dòng)一些方法的實(shí)現(xiàn)誉裆,起碼 22.0.1 和 25.3.1 差別還是有的,在網(wǎng)絡(luò)上缸濒,許許多多的使用教程都還是 2014 2015 年的教程足丢,嘗試了一下,許多方法的參數(shù)已經(jīng)不同了庇配,也有的權(quán)限變更斩跌,有的方法干脆就被干掉了,完全找不到存在過(guò)的痕跡捞慌,因此這里簡(jiǎn)單寫一下 25.3.1 的使用耀鸦。
1. 簡(jiǎn)單使用 TabLayout + ViewPager +Fragment
布局:
LinearLayout - vertical
==>TabLayout - main_tablayoutId
==>ViewPager - main_viewpagerId
MainActivity:
// find view
mTabLayout = ((TabLayout) findViewById(R.id.main_tablayoutId));
mViewPager = ((ViewPager) findViewById(R.id.main_viewpagerId));
// init data
final String[] titles = {"111","222","333","444","555"};// tab title
final List<Fragment> fragments = new ArrayList();// tab fragment
for (int i = 0; i < 5; i++) {
fragments.add(new BlankFragment());
}
// 設(shè)置 viewpager 適配器
mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {// 獲取 tab 對(duì)應(yīng)的 fragment
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {// 獲取 tab 對(duì)應(yīng)的 title
return titles[position];
}
});
mTabLayout.setTabGravity(TabLayout.GRAVITY_FILL);// 設(shè)置排列模式 (充滿 - 居中)
mTabLayout.setTabMode(TabLayout.MODE_FIXED);// 設(shè)置滾動(dòng)模式 (固定 - 滾動(dòng))
mTabLayout.setupWithViewPager(mViewPager);// 需要在 viewpager 設(shè)置適配器之后
2.TabLayout 屬性介紹
// 常用
// 指示器
tabIndicatorHeight
tabIndicatorColor
// 文字 - 在沒有設(shè)置 CustomView 的時(shí)候有效
tabTextColor
tabSelectedTextColor
// 背景
tabBackground
// 模式
tabMode
tabGravity
// tabview 的 padding 值比較大時(shí)會(huì)填掉 tabview 的內(nèi)容布局,tablayout 的高度并不會(huì)變化(內(nèi)部有一個(gè) defaultHeight 值啸澡,決定了 tablayout 的高度)
tabPadding
tabPaddingStart
tabPaddingTop
tabPaddingEnd
tabPaddingBottom
// text 的樣式
tabTextAppearance
// 第一個(gè) tab 距離左邊的偏移距離
tabContentStart
// tab 最小寬度
tabMinWidth
五袖订、關(guān)于自定義 TabView
鏈接:Android Design Support Library系列之一:TabLayout的使用
上面的文章我覺得寫得總結(jié)得很到位了,我就不再班門弄斧嗅虏。但是文章最后寫的關(guān)于 indicator 寬度的設(shè)置部分提到了一個(gè)方法 setIndicator(tablayout, marginLeft, marginRight) 洛姑,這個(gè)方法在我現(xiàn)在使用的 25.3.1 版本中并沒有,所以才做了上面的提取操作皮服。有可能還會(huì)有其他方法的不同楞艾,各位看官望知悉参咙。