前言
今天給大家帶來Material design系列的第四篇文章,TabLayout的使用,首先說明一下,什么是TabLayout,這里引用一下源碼中對TabLayout的介紹
TabLayout provides a horizontal layout to display tabs.
意思很明確,TabLayout提供了一個水平的布局用來展示Tabs。
那么在開發中相信大家在開發中經常會看到這樣的ui
像這樣多個tab切換,其實就可以用TabLayout來實現。
使用
首先在你的布局文件中加入該控件
然后在代碼中找到控件,并給他設置幾個tab
做到這一步你就能看到這樣的效果(PS:剛出iPhone8,我也來蹭一波熱度)
是不是很簡單,你只需要做這么一點操作就能實現tab切換的效果。
結合ViewPager使用
當然,在開發中,我們一般都是結合ViewPager來使用達到切換的目的,那么怎么做呢?
首先在布局文件中加入ViewPager控件
然后在代碼中找到該控件
附上adapter代碼
private class DemoPager extends FragmentPagerAdapter {
private final List<Fragment> fragments;
private final List<String> titles;
public DemoPager(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
super(fm);
this.fragments = fragments;
this.titles = titles;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments == null ? 0 : fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
做到這一步,我們就可以看到這樣的效果。
TabLayout屬性介紹
-
app:tabSelectedTextColor:改變選中字體的顏色
-
app:tabTextColor:改變未選中字體的顏色
-
app:tabIndicatorColor:改變指示器顏色
-
app:tabBackground:改變背景色
-
app:tabIndicatorHeight:改變指示器高度
這五個屬性我都使用了,這里給大家看看效果(前方高能,非戰斗人員請迅速撤離)
哈哈,這個配色雖然有點辣眼睛,不過這不是重點,效果實現了就好,畢竟我們是開發人員,不是UI對吧,o(∩_∩)o 哈哈。
-
添加圖標
如果只是文字,可能會有點單調,我們可以加一個圖標在上面,就像這樣,調用getTabAt拿到對應的tab,然后調用setIcon方法即可
-
app:tabMode
這個屬性的作用就是修改TabLayout的屬性,有2個值,fixed和scrollable,默認是fixed,fixed就是固定的,scrollable就是可以滑動,舉個栗子,我先多加幾個標題
-
app:tabGravity:內容的顯示模式,center是居中,fill是填滿
-
app:tabMaxWidth:tab最大寬度
-
app:tabMinWidth:tab最小寬度
-
app:tabContentStart:tab的"margin"
TabLayout的監聽事件
修改指示器長度
相信用過tablayout的朋友都知道,我們并不能找到直接修改指示器寬度的方法,這里就需要大家自己做操作了,當然這里會給大家帶來一種方法
public void setIndicator(TabLayout tabs, int leftDip, int rightDip) {
Class<?> tabLayout = tabs.getClass();
Field tabStrip = null;
try {
tabStrip = tabLayout.getDeclaredField("mTabStrip");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
tabStrip.setAccessible(true);
LinearLayout llTab = null;
try {
llTab = (LinearLayout) tabStrip.get(tabs);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());
for (int i = 0; i < llTab.getChildCount(); i++) {
View child = llTab.getChildAt(i);
child.setPadding(0, 0, 0, 0);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
params.leftMargin = left;
params.rightMargin = right;
child.setLayoutParams(params);
child.invalidate();
}
}
然后你只需要在拿到tablayout之后調用一下該方法就好,就像這樣
效果圖
添加分割線
這個需求并不多,但是如果碰到了,那就乖乖的做吧。。。
//先拿到tablayout
LinearLayout linearLayout = (LinearLayout) tabLayout.getChildAt(0);
linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
//傳入一張圖片,我這里就用shape代替了
linearLayout.setDividerDrawable(ContextCompat.getDrawable(this,
R.drawable.divider));
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/red"/>
<size android:width="2dp"/>
</shape>
自定義視圖setCustomView
比如我們要實現tab有兩行文字的需求,如果文字大小都相同,我們直接用\n換行就可以實現,就像這樣
如果上面textView字體大小與下面不同,或者一些奇奇怪怪的需求,那么就需要用到setCustomView了。
先給大家看一下效果圖
這樣的效果你用單純的\n肯定是實現不了的對吧。
這里給大家貼一下上述需求實現的代碼,大家可以做一個參考應用到自己的項目里面
//先把你要的標題放到集合中
List<String> topTitles = new ArrayList<>();
topTitles.add("java");
topTitles.add("php");
topTitles.add("python");
List<String> bottomTitles = new ArrayList<>();
bottomTitles.add("c語言");
bottomTitles.add("c++");
bottomTitles.add(".net");
//其次添加幾個tab
tabLayout.addTab(tabLayout.newTab());
tabLayout.addTab(tabLayout.newTab());
tabLayout.addTab(tabLayout.newTab());
//通過getTabCount方法拿到tab的數量
int tabCount = tabLayout.getTabCount();
for (int i = 0; i < tabCount; i++) {
View view = View.inflate(this, R.layout.custom_view, null);
((TextView) view.findViewById(R.id.tv_top)).setText(topTitles.get(i));
((TextView) view.findViewById(R.id.tv_bottom)).setText(bottomTitles.get(i));
//調用setCustomView方法設置自定義布局
tabLayout.getTabAt(i).setCustomView(view);
}
自定義布局文件我就不貼了,就是兩個TextView而已。
這里要注意了,當你這樣做了之后,app:tabSelectedTextColor和app:tabTextColor屬性就失效了,我們需要手動解決這個問題,給tablayout設置一個監聽
手動設置之后,確實能實現顏色切換的效果,但是這里還有一個問題,不知道大家發現沒有,那就是你必須挨個點擊之后,顏色改變才能生效,那么怎么辦呢,這里剛開始想到的是調用
mTabLayout.getTabAt(0).select();
手動選擇第一個tab,但是發現這樣并不能達到效果,所以最終的解決方案是這樣的
拿到listener對象,手動調用里面的方法,這樣效果就能實現了
總結
好了,TabLayout的使用到此結束了,祝大家工作順心,看到這里了你還不點贊,你的良心不會痛么(┬_┬)