国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

android TabLayout的指示器寬度問題

2019-10-22 18:13:10
字體:
供稿:網(wǎng)友

最近碰到一個需求,因為是我比較感興趣的android/252228.html">TabLayout的,所以記錄一下吧。

  1. 產(chǎn)品需求:希望上部導(dǎo)航欄中的指示器寬度略大于文字寬度;
  2. 技術(shù)方案:TabLayout配合ViewPager;
  3. 問題分析: 原生TabLayout的指示器寬度等于每個tab的寬度,遠大于 tab內(nèi)文字標(biāo)題的寬度。

原因分析:

TabLayout(TL)繼承自HorizontalScrollView,其只能添加一個子控件,這個子控件便是TL內(nèi)部私有類–SlidingTabStrip,其繼承自LinearLayout。指示器怎么加上的呢?便是在該類的onDraw方法中:

 @Overridepublic void draw(Canvas canvas) { super.draw(canvas); // Thick colored underline below the current selection if (mIndicatorLeft >= 0 &&  mIndicatorRight > mIndicatorLeft) {  canvas.drawRect(mIndicatorLeft,  mIndicatorRight, getHeight(),  mSelectedIndicatorPaint); }}

即指示器是與這個SlidingTabStrip容器伴生存在,其寬度,由mIndicatorLeft和mIndicatorRight確定,而這二者,由tab的寬度決定,因為本文不會詳細描述TL的源碼,所以這里直接報出結(jié)論:這個指示器的寬度設(shè)置由tab寬度決定,而tab在mode=fix情況下,是符合linearLayout中weight控制的,因此,也沒法通過tab的寬度來影響指示器的寬度,比較囧的是,源碼中也沒給tab設(shè)置個Margin什么的,另外,源碼中也沒有暴露set等方法來改變指示器寬度,否則也不會有此問題了。

解決方案1:

百度的方案基本集中在反射,使用麻煩,有時還不好用。

這個的思路來自stackoverflow,大致過程是 由TL拿到其唯一的子類,即SlidingTabStrip,然后遍歷再拿到其各子View,然后為每個子View設(shè)置Margin,這就相當(dāng)于給每個tab設(shè)置margin,那么指示器的寬度自然也就跟著改變了。show code:

public static void reduceMarginsInTabs(TabLayout tabLayout, int marginOffset) {  View tabStrip = tabLayout.getChildAt(0);  if (tabStrip instanceof ViewGroup) {   ViewGroup tabStripGroup = (ViewGroup) tabStrip;   for (int i = 0; i < ((ViewGroup) tabStrip).getChildCount(); i++) {    View tabView = tabStripGroup.getChildAt(i);    if (tabView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {     ((ViewGroup.MarginLayoutParams) tabView.getLayoutParams()).leftMargin = marginOffset;     ((ViewGroup.MarginLayoutParams) tabView.getLayoutParams()).rightMargin = marginOffset;    }   }  tabLayout.requestLayout();  } }

這種方式的限制是:最多只能讓指示器與tab等寬,無法繼續(xù)減小指示器的寬度。

解決方案2:

本方案屬于自定制指示器顯示,相對比較靈活,能解決方案1的tab等寬問題,但是其缺點是不能保留指示器的動畫。具體過程:

TL中tab可以設(shè)置自定義view,方法是setCustomView(@Nullable View view) ,也就是說,完全可以不用TL中那套,直接自定義布局即可。在tab源碼的update方法中有這么一句:

 mCustomTextView = (TextView) custom.findViewById(android.R.id.text1); if (mCustomTextView != null) {  mDefaultMaxLines = TextViewCompat.getMaxLines(mCustomTextView); } mCustomIconView = (ImageView) custom.findViewById(android.R.id.icon);

里面的android.R.id.text1和android.R.id.icon就是TL中tab能跟隨滑動改變狀態(tài)的兩個view的id,我們自定義的時候可以讓對應(yīng)的view也這么設(shè)置id即可。而指示器,大可屏蔽原生TL的,直接在自定義布局的合適位置,加個view就行。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 大埔县| 镇原县| 乐陵市| 自贡市| 山丹县| 苍梧县| 来凤县| 阿拉善盟| 阿瓦提县| 微博| 富源县| 姚安县| 乌恰县| 行唐县| 中西区| 玉山县| 惠来县| 石家庄市| 禄丰县| 岢岚县| 余庆县| 瓦房店市| 垫江县| 新疆| 都匀市| 香河县| 延津县| 南川市| 雷州市| 贵港市| 永康市| 黄石市| 布尔津县| 修武县| 湖口县| 新安县| 高雄市| 阿图什市| 巴林左旗| 扎赉特旗| 巴林左旗|