TabLayout是開發(fā)中經(jīng)常使用到的控件镜悉,經(jīng)常與ViewPager一起配合使用,一組tab医瘫,可以點(diǎn)擊侣肄、可以滾動(dòng)。這不醇份,我們的app中也是用到了這個(gè)控件稼锅,之前對(duì)這個(gè)控件只停留在最基本的用法吼具,因此開發(fā)時(shí)也去查了些資料,趁著周末矩距,就系統(tǒng)地再學(xué)習(xí)一下拗盒。
基本操作
使用之前,首先需要在gradle文件中加入design庫锥债,
implementation 'com.android.support:design:28.0.0'
首先看一下最默認(rèn)的行為與效果陡蝇。 代碼如下:
<?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"
tools:context=".MainActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="56dp">
</android.support.design.widget.TabLayout>
</android.support.constraint.ConstraintLayout>
tabLayout.addTab(tabLayout.newTab().setText("Tab 1").setIcon(R.mipmap.ic_launcher));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3").setIcon(R.mipmap.ic_launcher));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
Toast.makeText(MainActivity.this,tab.getText(),Toast.LENGTH_SHORT).show();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
Toast.makeText(MainActivity.this,tab.getText(),Toast.LENGTH_SHORT).show();
}
});
setOnTabSelectedListener是一個(gè)過時(shí)方法,官方建議使用addOnTabSelectedListener代替哮肚,其中監(jiān)聽器接口是一樣的毅整,分別表示tab選中、未選中绽左,再次選中狀態(tài)悼嫉。其中再次選中狀態(tài)可以用于實(shí)現(xiàn)在選中tab的前提下,再點(diǎn)擊時(shí)拼窥,滾動(dòng)到最頂部的效果戏蔑,比如很多資訊類app就是這么實(shí)現(xiàn)的。
效果圖如下:
默認(rèn)效果可以看到指示器紅色鲁纠,三個(gè)tab平分布局总棵,有icon的顯示在文字上方。 如果TabLayout的寬度wrap_content改含,那么三個(gè)tab將會(huì)擠到左邊情龄,每個(gè)tab的效果是wrap_content。
以上tab是通過代碼添加的捍壤,也可以在xml中進(jìn)行添加骤视,效果等效于
<?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"
tools:context=".MainActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="56dp">
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@mipmap/ic_launcher"
android:text="Tab 1" />
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Tab 2" />
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@mipmap/ic_launcher"
android:text="Tab 3" />
</android.support.design.widget.TabLayout>
</android.support.constraint.ConstraintLayout>
xml屬性說明
對(duì)于TabLayout的樣式修改,一些可以通過修改屬性就行修改鹃觉。
修改指示器
可以修改指示器的顏色和高度专酗,比如:
<android.support.design.widget.TabLayout
app:tabIndicatorColor="@android:color/holo_green_dark"
app:tabIndicatorHeight="10dp"
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="56dp"/>
效果如下:
修改文字樣式
- 選中和未選中顏色設(shè)置
app:tabSelectedTextColor="#FF0000"
app:tabTextColor="#0000FF"
效果如下圖:
- 修改文字大小
使用textAppearence屬性,在style文件中設(shè)置大小盗扇。
app:tabTextAppearance="@style/my_tab_text_style"
my_tab_text_style內(nèi)容如下:
<style name="my_tab_text_style">
<item name="android:textSize">20sp</item>
<item name="android:textStyle">bold</item>
</style>
效果如下:
修改tab樣式
-
使用padding參數(shù)祷肯,可以使用tabPadding進(jìn)行設(shè)置,比如:
<android.support.design.widget.TabLayout app:tabPaddingTop="20dp" android:paddingBottom="20dp" android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content">
可以看到預(yù)覽圖的效果如下:
-
tabMode疗隶。tabMode支持兩種值佑笋,MODE_FIXED和MODE_SCROLLABLE;當(dāng)tab比較多斑鼻,一屏容納不下時(shí)蒋纬,會(huì)使用MODE_SCROLLABLE,這時(shí)可以隱藏部分MODE;而FIXED的就會(huì)始終顯示颠锉。
當(dāng)在xml布局中添加了很多TabItem后法牲,預(yù)覽效果如下圖:
這時(shí)使用的就是FIXED模式史汗,可以看到TabLayout默認(rèn)就是FIXED模式琼掠;當(dāng)改成MODE_SCROLLABLE后,
app:tabMode="scrollable"
預(yù)覽樣式如下圖:
-
Tab位置停撞。當(dāng)只有三個(gè)tab時(shí)瓷蛙,默認(rèn)分散了,如果想三個(gè)tab聚合起來戈毒,可以通過設(shè)置tabGravity屬性進(jìn)行設(shè)置艰猬,比如:
app:tabGravity="center"
設(shè)置后的效果如下:
設(shè)置前的效果就是前面三個(gè)tab平鋪的效果。改屬性的默認(rèn)值是fill埋市。
另外冠桃,可以通過設(shè)置tabContentStart設(shè)置偏移量,類似margin道宅。
比如設(shè)置:
app:tabContentStart="100dp"
后的效果如下圖:
-
設(shè)置tab背景食听。tabBakcground屬性,比如設(shè)置的樣式如下:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <size android:width="50dp" android:height="30dp" ></size> <gradient android:startColor="#FF0000" android:endColor="#0000FF" ></gradient> </shape>
效果圖:
tab寬度污茵,可以通過設(shè)置tabMaxWidth和tabMinWidth進(jìn)行限制樱报。
TabItem樣式自定義
以上的xml樣式,都可以通過相應(yīng)的set方法進(jìn)行設(shè)置泞当,但是如果想改變默認(rèn)的tab樣式迹蛤,那么就需要代碼的操作了。默認(rèn)的tab樣式襟士,icon在上盗飒,text在下;下面改個(gè)icon在左陋桂,text在右的樣式箩兽。
首先定義一個(gè)布局:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="48dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:padding="12dp"
android:id="@+id/iv_icon"
tools:src="@mipmap/ic_launcher"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:textSize="18sp"
android:textColor="#333333"
android:id="@+id/tv_text"
android:layout_width="0dp"
android:layout_height="21dp"
app:layout_constraintLeft_toRightOf="@id/iv_icon"
app:layout_constraintRight_toRightOf="parent"
tools:text="hha" />
</android.support.constraint.ConstraintLayout>
然后在代碼中更改TabLayout現(xiàn)有Tab樣式,代碼如下:
tabLayout=findViewById(R.id.tabLayout);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
View view=LayoutInflater.from(this).inflate(R.layout.my_tab_layout,null);
tab.setCustomView(view);
((ImageView)view.findViewById(R.id.iv_icon)).setImageDrawable(tab.getIcon());
((TextView)view.findViewById(R.id.tv_text)).setText(tab.getText());
}
運(yùn)行結(jié)果如下圖:
可以看到tab樣式已經(jīng)變成了icon在左章喉,文字在右的樣式汗贫。
集成ViewPager
布局如下:
<?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"
tools:context=".MainActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="56dp">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
app:layout_constraintTop_toBottomOf="@id/tabLayout"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
android:layout_height="0dp"></android.support.v4.view.ViewPager>
</android.support.constraint.ConstraintLayout>
代碼如下:
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] imgs=new int[]{
R.drawable.pic_11,
R.drawable.pic_12,
R.drawable.pic_11
};
private String[] tabs=new String[]{
"Tab 1",
"Tab 2",
"Tab 3",
};
private List<ImgFragment> imgFragments=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout=findViewById(R.id.tabLayout);
viewPager=findViewById(R.id.viewpager);
for (int i = 0; i < imgs.length; i++) {
imgFragments.add(ImgFragment.newInstance(imgs[i]));
}
viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int i) {
return imgFragments.get(i);
}
@Override
public int getCount() {
return imgFragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return tabs[position];
}
});
tabLayout.setupWithViewPager(viewPager);
}
}
運(yùn)行效果如下:
這里需要注意的是:當(dāng)調(diào)用了setupWithViewPager之后,tab值默認(rèn)將會(huì)從getPageTitle中獲冉胀选落包;如果這個(gè)時(shí)候沒有重寫PageAdapter的getPageTitle,那么效果將會(huì)如下圖:
這個(gè)時(shí)候可以發(fā)現(xiàn)TabLayout上面都是空的摊唇,但其實(shí)是有tab的咐蝇,只不過tab內(nèi)容為空而已。這個(gè)時(shí)候可以通過代碼重新設(shè)置巷查,比如:
tabLayout.setupWithViewPager(viewPager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab=tabLayout.getTabAt(i);
tab.setText(tabs[i]);
tab.setIcon(imgs[i]);
}
效果如下圖:
可以看到有序,不止設(shè)置了text抹腿,還設(shè)置了title,使用PageAdapter只能設(shè)置text旭寿。
總結(jié)
至此警绩,TabLayout的基本用法也就是這樣了;除了這個(gè)盅称,還有與Toolbar以及協(xié)調(diào)布局共同使用的情況肩祥,這個(gè)以后有機(jī)會(huì)會(huì)繼續(xù)深入的學(xué)習(xí)下。