一、内部组成元素及分析
- TabLayout的三个基本组成元素:Tab、TabView、SlidingTabStrip
- TabLayoutOnPageChangeListener和ViewPagerOnTabSelectedListener实现了ViewPager类的两个接口,作用是监听ViewPager页面改变和Tab选中状态。
- PagerAdapterObserver为观察者监控PagerAdapter数据变化。
- 所以在自定义TabLayout前,先设计好Tab模式,并且官方扩展了一个TabView子控件件。
- 自定义TabLayout的工作,还要通过接口完成和ViewPager的交互,通过PagerAdapterObserver,确保TabLayout能够正常工作。
二、内部类,Tab模型
内部类Tab定义了Tab的成员变量,并提供set和get方法,并封装了tab的属性设置方法,(setIcon、setCustomView)

三、内部类,自定义的TabView
TabView继承自LinearLayout,默认的tab布局,可以同时显示图片和文字;
其构造器设置了TabView在TabLayout中的状态,这些状态属性都是固定的不可变的,所以也决定TabView设置受到限制。
public TabView(Context context) {
super(context);
if (mTabBackgroundResId != 0) {
ViewCompat.setBackground(
this, AppCompatResources.getDrawable(context, mTabBackgroundResId));
}
ViewCompat.setPaddingRelative(this, mTabPaddingStart, mTabPaddingTop,
mTabPaddingEnd, mTabPaddingBottom); //设置padding
setGravity(Gravity.CENTER); //居中显示
setOrientation(VERTICAL); //布局方向
setClickable(true);//可点击
ViewCompat.setPointerIcon(this,
PointerIconCompat.getSystemIcon(getContext(), PointerIconCompat.TYPE_HAND));
}
看源码setCustomView(@LayoutRes int resId) 最终会调用到TabView的update方法中去:
update方法,先判断设置的customView是否为空,是否有父类,移除TabView中默认的组件,分别获取TextView和Icon,如果获取失败,仍然使用默认的组件;
这里要注意,自定义的TextView的ID必须设置为android.R.id.text1,Icon必须设置为android.R.id.icon;因为代码中好像是写死的;
四、SlidingTabStrip,Tab下滑线
这个自定义view SlidingTabStrip是私有内部类,它继承自LinearLayout,作用为获取tab的最宽宽度,设置SlidingTabStrip的宽度,并设置一个动画,随着tab的改变绘制;
因为它是私有的,所以就固定了他的样式只能是简单的直线形式,如果需要特殊样式的下划线,就需要自定义了
SlidingTabStrip。它有一个构造器:
SlidingTabStrip(Context context) {
super(context);
setWillNotDraw(false);//重写draw()不起作用时,需要添加这么一句
mSelectedIndicatorPaint = new Paint();
}
单看这个构造器就知道使用SlidingTabStrip超级简单,在这个构造器源码中,有一个地方需要注意,因为在我们自定义view中会用到,就是setWillNotDraw(false);但看这句的字面意思就不难猜到,双重否定等于肯定,让它进行绘制。当我们自定义的view在onDrow()不起作用时,一种方法是在构造器里设置背景颜色,一种就是添加这句语句。原因可以进一步参考ViewGroup为什么不会调用onDraw
代码结构极易一目了然。在onMeasure()获取最宽tab宽度,并设置为此控件的宽度;在onLayout()进行动画并更新Indicator位置;最后draw()。
五,ViewPager的监听器:TabLayoutOnPageChangeListener
这个类是实现ViewPager.OnPageChangeListener的一个内部类,作用是监听到ViewPager页面改变的时候,更新tab和Indicator。首先注意这个类是public,并且被static修饰,static一般用来修饰成员变量或或成员函数,有static修饰内部类有什么特别呢,那就是在外面使用这个类的时候,不需要先new内部类所在的类(如在这里为TabLayout)的实例,可以直接new这个内部类的实例,比如:
TabLayout.TabLayoutOnPageChangeListener listener=new TabLayout.TabLayoutOnPageChangeListener;
六,TabLayout的tab选中监听:ViewPagerOnTabSelectedListener
public static class TabLayoutOnPageChangeListener implements ViewPager.OnPageChangeListener {}
public static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener {}
除了这个内部类也是public static外,与ViewPager.OnPageChangeListener相对应的是这里实现的是TabLayout.OnTabSelectedListener;这个接口是TabLayout中定义的接口,在这里实现的作用是使TabLayout中的tab能够和ViewPager的pager保持同步。
然后在TabLayout中有一个方法:
public void setOnTabSelectedListener(OnTabSelectedListener onTabSelectedListener) {
mOnTabSelectedListener = onTabSelectedListener;
}
mOnTabSelectedListener是这个内部类ViewPagerOnTabSelectedListener的一个实例,我们使用TabLayout时,就是通过调用这个方法设置tab的监听事件。
七,数据监听:PagerAdapterObserver
这是一个观察者,继承自DataSetObserver,DataSetObserver我不多说了,关于介绍推荐Android中的观察者DataSetObservabl

最低0.47元/天 解锁文章
1972

被折叠的 条评论
为什么被折叠?



