最近的项目中,要在一个模块当中,增加一个tab分类,每个分类展示不同的数据,理所当然的想到了用TabLayout+ViewPager+Fragment来实现,因此也遇到了一些TabLayout的坑,记录一下这些血泪史。。。
1. TabLayout最小宽度
因为分类一共有6个,屏幕宽度不够放下所有的tab,只能设置成滚动tab,每个tab设置左右边距13dp,很简单,TabLayout都有对应的属性可以设置。
1 | <android.support.design.widget.TabLayout |
结果发现每个tab的宽度很大,边距比13dp还大,这肯定是逃不过UI小姐姐的眼睛的,小姐姐要求边距一定只能13dp。行,那就解决问题,换了几个padding值,感觉还是那么大,好像没什么变化,只好从TabLayout的源码入手。源码看着看着,发现在初始化的时候,有一个属性
1 | this.scrollableTabMinWidth = res.getDimensionPixelSize(dimen.design_tab_scrollable_min_width); |
而这个design_tab_scrollable_min_width有72dp,所以就算文字只有1个字,也要保持72dp的宽度。但是这个属性好像不能修改,接着看源码。
1 | private int getTabMinWidth() { |
看这个获取minWidth,在我们没有设置minWidth的时候,会判断模式是不是滚动模式,如果是,就取scrollableTabMinWidth,这就好办了,只要我们设置一个minWidth,就可以自己设置padding值了。
1 | <android.support.design.widget.TabLayout |
TabLayout的UI问题算是搞定了。
2. TabLayout抖动问题
简单描述一下抖动问题,就是当TabLayout的tab数量超出屏幕并且可以滚动的时候,手动滚动TabLayout,选择一个在屏幕外的tab点击,TabLayout会先滚动回原来的tab,再滚动到点击的tab位置,出现类似抖动的现象,具体可以看使用系统TabLayout的app快来修Bug。
按照上面那篇的文章进行更改,结果发现用反射找不到mPageChangeListener,不知道是不是Android9开始限制反射的原因,导致我的Android10手机无法用反射更改这个listener,那只能自己再找其他方法了。
根据上面那个作者的思路,我们看pageChangeListener在哪里使用。
1 | // TabLayout源码 |
可以看到,在TabLayout关联viewpager的时候,viewpager先移除已经存在的pageChangeListener,后面若pageChangeListener为null,就初始化一个,然后重新add进去。既然问题出在TabLayoutOnPageChangeListener而viewpager的addOnPageChangeListener是public接口,那我们可以修改viewpager的listener啊,遂更改:
1 | // 先清空所有的pagechangelistener,会移除tablayout添加进去的那个,要在setupWithViewPager后面调用 |
TabLayout的抖动问题也算圆满解决了。
还有一个Fragment切换,里面的recyclerbview页面变成空白的问题待解决,先记一下。