Android 开源项目源码解析 -->PagerSlidingTabStrip 源码解析(十八)
2016-09-28 10:52
639 查看
项目:PagerSlidingTabStrip
pagerSlidingTabStrip 实现联动效果的原理是,它引用了 ViewPager 的
不是自身的
通过
可设置字库属性。 通过提供方法如滑动指示器 下划线 tab 风格线 tab 权重等达到自定义的效果。
兼容 Android 支持库中的 ViewPager 的一个滑动分页指示器的控件。
滑动时实现 TextView 颜色状态的联动
支持文字导航指示,可指定选中的 pager 导航字体属性
支持图片导航指示,可高亮选中 pager 页导航背景
很好的扩展性
3.2.1
在 gradle 中
3.2.2 在 layout 布局文件中引入 PagerSlidingTabStrip,通常布局在 viewpager 上面。如下:
3.2.3 在 oncreate 方法中(或 Fragment 的 onCreateView)中,绑定 PagerSlidingTabStrip 到 Viewpager
3.2.4 如果你的 view pager 使用到 OnPageChangeListener。你应该通过这个 PagerSlidingTabStrip 控件设置而不是 Viewpager。如下:
根据你的需要修改下面的值
pagerSlidingTabStrip 实现联动效果的原理是,它引用了 ViewPager 的 OnPageChangeListener。但是 viewpager 注册的 listener 不是自身的
pagerSlidingTabStrip 内部类
scrollToChild,tab 的滑动位置 实现如下:
接下来说下 addTextTab addIconTab。即 tab 是 text 还是 icon。如果是 icon 的话,通过 viewpager 的 adapter 实现接口
icontab。
请参考公共技术点
viewdrawflow部分
在 pagerSlidingTabStrip 中重写了 onDraw 函数 绘画滑动指示器; 绘画整个 tabs 下划线; 绘画 tab 之间间隔线。代码如下
该库有很好的自定义性和扩展性。比如修改滑动指示器为一张图片【目前为设定颜色值和高度来决定】
ViewPagerindicator 源码解析
How Android Draws Views
View
绘制流程
Android View 绘制流程
Android 中 View 绘制流程以及 invalidate()等相关方法分析
Android 中 measure 过程、WRAP_CONTENT 详解以及 xml 布局文件解析流程浅析(下)
View
事件传递
Andriod 从源码的角度详解 View,ViewGroup 的 Touch 事件的分发机制
Android 中 Touch(触屏)事件传递机制
1. 总体设计
pagerSlidingTabStrip 实现联动效果的原理是,它引用了 ViewPager 的OnPageChangeListener。 但是 viewpager 注册的 listener
不是自身的
OnPageChangeListener,而是 pagerSlidingTabStrip 内部类
PageListener。
通过
PageListener实现对对 viewpager 和 tab 的封装。从而实现滑动联动效果。 可以设置 tab 的类型为 textview 还是 icon。对于 textview
可设置字库属性。 通过提供方法如滑动指示器 下划线 tab 风格线 tab 权重等达到自定义的效果。
2. 流程图
3. 功能介绍
3.1 特性介绍
兼容 Android 支持库中的 ViewPager 的一个滑动分页指示器的控件。滑动时实现 TextView 颜色状态的联动
支持文字导航指示,可指定选中的 pager 导航字体属性
支持图片导航指示,可高亮选中 pager 页导航背景
很好的扩展性
3.2 集成及使用指南
3.2.1
在 gradle 中
dependencies { compile 'com.astuetz:pagerslidingtabstrip:1.0.1' }
3.2.2 在 layout 布局文件中引入 PagerSlidingTabStrip,通常布局在 viewpager 上面。如下:
<com.astuetz.PagerSlidingTabStrip android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="48dip" />
3.2.3 在 oncreate 方法中(或 Fragment 的 onCreateView)中,绑定 PagerSlidingTabStrip 到 Viewpager
// 初始化 ViewPager 和 Adapter ViewPager pager = (ViewPager) findViewById(R.id.pager); pager.setAdapter(new TestAdapter(getSupportFragmentManager())); // 绑定 PagerSlidingTabStrip 到 ViewPager 上 PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs); tabs.setViewPager(pager);
3.2.4 如果你的 view pager 使用到 OnPageChangeListener。你应该通过这个 PagerSlidingTabStrip 控件设置而不是 Viewpager。如下:
// continued from above tabs.setOnPageChangeListener(mPageChangeListener);
3.3 用户定制
根据你的需要修改下面的值pstsIndicatorColor滑动指示器的颜色
pstsUnderlineColor整个 view【PagerSlidingTabStrip】下划线的颜色
pstsDividerColortabs 之间分割线的颜色
pstsIndicatorHeight滑动指示器的高度
pstsUnderlineHeight整个 View【PagerSlidingTabStrip】下滑线的高度
pstsDivviderPadding分割线上部、下部的内间距
pstsTabPaddingLeftRight每个 tab 左右内间距
pstsScrollOffset选中 tab 的滑动的距离
pstsTabBackground每个 tab 的背景图片,使用 StateListDrawable
pstsShouldExpand如果设置为 true,每个 tab 的宽度拥有相同的权重
pstsTextAllCaps如果设置为 true,所有的 tab 字体转为大写
4. 详细设计
4.1 类详细介绍
4.2 核心方法及功能介绍
pagerSlidingTabStrip 实现联动效果的原理是,它引用了 ViewPager 的 OnPageChangeListener。但是 viewpager 注册的 listener 不是自身的OnPageChangeListener,而是
pagerSlidingTabStrip 内部类
PageListener。通过 PageListener 实现对对 viewpager 和 tab 的封装。从而实现滑动联动效果。下面结合代码详细说明
private class PageListener implements OnPageChangeListener { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //当前 view 的位置也即 tab 的位置 currentPosition = position; //当前 view 滑动的距离。其中 currentPositionOffset 为 float,介于 0~1 代表相对于 tab 宽偏移的比例 currentPositionOffset = positionOffset; //根据上面得到的 view 的位置和偏移位置,来同步 tab 的位置和偏移距离。 scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth())); //重绘 view,实现 tab 滑动的效果。 invalidate(); //下面的 delegatePageListener 就是我们设置的 viewpager.setOnPageChangeListener.而现在把它封装在整个 pagerSlidingTabStrip 中,实现 viewpager 滑动的效果。 if (delegatePageListener != null) { delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels); } } @Override public void onPageScrollStateChanged(int state) { //滑动结束。positionOffset 归零 if (state == ViewPager.SCROLL_STATE_IDLE) { scrollToChild(pager.getCurrentItem(), 0); } //调用 viewpager.setOnPageChangeListener if (delegatePageListener != null) { delegatePageListener.onPageScrollStateChanged(state); } } @Override public void onPageSelected(int position) { //调用 viewpager.setOnPageChangeListener if (delegatePageListener != null) { delegatePageListener.onPageSelected(position); } } }
scrollToChild,tab 的滑动位置 实现如下:
private void scrollToChild(int position, int offset) { if (tabCount == 0) { return; } int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset; if (position > 0 || offset > 0) { newScrollX -= scrollOffset; } //滑动到的位置。 if (newScrollX != lastScrollX) { lastScrollX = newScrollX; scrollTo(newScrollX, 0); } }
接下来说下 addTextTab addIconTab。即 tab 是 text 还是 icon。如果是 icon 的话,通过 viewpager 的 adapter 实现接口
IconTabProvider。来确定
icontab。
for (int i = 0; i < tabCount; i++) { if (pager.getAdapter() instanceof IconTabProvider) { addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i)); } else { addTextTab(i, pager.getAdapter().getPageTitle(i).toString()); } }
4.3 View 绘制机制
请参考公共技术点viewdrawflow部分
在 pagerSlidingTabStrip 中重写了 onDraw 函数 绘画滑动指示器; 绘画整个 tabs 下划线; 绘画 tab 之间间隔线。代码如下
// draw indicator line rectPaint.setColor(indicatorColor); // default: line below current tab View currentTab = tabsContainer.getChildAt(currentPosition); float lineLeft = currentTab.getLeft(); float lineRight = currentTab.getRight(); // if there is an offset, start interpolating left and right coordinates between current and next tab if (currentPositionOffset > 0f && currentPosition < tabCount - 1) { View nextTab = tabsContainer.getChildAt(currentPosition + 1); final float nextTabLeft = nextTab.getLeft(); final float nextTabRight = nextTab.getRight(); lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft); lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight); } canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint); // draw underline rectPaint.setColor(underlineColor); canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint); // draw divider dividerPaint.setColor(dividerColor); for (int i = 0; i < tabCount - 1; i++) { View tab = tabsContainer.getChildAt(i); canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); }
5. 杂谈
该库有很好的自定义性和扩展性。比如修改滑动指示器为一张图片【目前为设定颜色值和高度来决定】
6.参考文献
ViewPagerindicator 源码解析
View 的绘制:
How Android Draws ViewsView
绘制流程
Android View 绘制流程
Android 中 View 绘制流程以及 invalidate()等相关方法分析
Android 中 measure 过程、WRAP_CONTENT 详解以及 xml 布局文件解析流程浅析(下)
TOUCH 事件处理
View事件传递
Andriod 从源码的角度详解 View,ViewGroup 的 Touch 事件的分发机制
Android 中 Touch(触屏)事件传递机制
相关文章推荐
- 【Android开源项目分析】TAB导航栏PagerSlidingTabStrip的使用和源码分析
- Android两级导航菜单栏的实现--FragmentTabHost结合ViewPager与Android 开源项目PagerSlidingTabStrip
- 关于阅读Android开源项目PagerSlidingTabStrip的理解
- Android PagerSlidingTabStrip 开源项目
- Android两级导航菜单栏的实现--FragmentTabHost结合ViewPager与Android 开源项目PagerSlidingTabStrip
- Android 开源项目源码解析 -->ViewPagerindicator 源码解析(十)
- Android两级导航菜单栏的实现--FragmentTabHost结合ViewPager与Android 开源项目PagerSlidingTabStrip
- Android开源项目PagerSlidingTabStrip
- PagerSlidingTabStrip 源码解析
- Android 开源项目源码解析 -->HoloGraphLibrary 源码解析(九)
- [Android初级]开源Widget之PagerSlidingTabStrip新手测试
- Android 开源项目源码解析 -->公共技术点之依赖注入(二)
- PagerSlidingTabStrip源码解析
- Android 开源项目源码解析 -->Volley 源码解析(十五)
- Android 开源项目源码解析 -->CircularFloatingActionMenu 源码解析(八)
- PagerSlidingTabStrip源码解析
- Android 开源项目源码解析 -->Android Universal Image Loader 源码分析(十四)
- Android 开源项目源码解析 -->Dagger 源码解析(十三)
- Android 开源项目源码解析 -->公共技术点之 Java 动态代理(五)
- Android 开源项目源码解析 -->公共技术点之 View 绘制流程(三)