高仿新浪微博头部的导航条
首先看一下微博的效果图:
再看一下我们的最终效果图:
仔细观察微博的效果:
- 关注页面滑到页面的一半宽度以上时会自动切换到热门页面。
- 看黄条的长度。当关注页面滑动一半时,黄条的长度到达“热门”两个字的接近右边,不会变长。反之,亦然。
- 选中的页面的字体颜色有变化。
- 黄色线的颜色是渐变的
导航条的整体构造
我们可以使用 HorizontalScrollView 来实现,HorizontalScrollView 只允许有一个子View,也就是图中的contextLi
,而他的子View包括一个装有TextView
的LinearLayout
和一个左右跑动的DynamicLine
,而在使用 TextView 填充 HorizontalScrollView 时,会出现两种情况:
- 字数很短,没有超出屏幕
- 字数很长,超出了屏幕宽度
得出以下:
- 通过
TextView的长度 + TextView的左右边距
与屏幕宽度
比较,判断 TextView 的总长度与屏幕宽度的关系。 - 导航条上面的分类字数较少时,要首先计算平分的每个 TextView 字体的宽度,然后指定 TextView 的左右边距。
- 字数长时,设置 TextView 的左右边距为默认边距
根据 TextView 的实际长度计算其左右边距代码:
1 | private int getTextViewMargins(String[] titles) { |
然后将相关的数据进行填充:
1 | private void createTextViews(String[] titles) { |
黄色的线-DynamicLine
可以看到黄色的线并不是一条线,而是一个圆角矩形。关于黄色圆角矩形的移动,只要更改圆角矩形的起始X坐标与终止X坐标,就可以让黄色条条进行移动了:主要用到了一个API:
1 | drawRoundRect(float rx, float ry, Paint paint) RectF rect, |
自定义一个 DynamicLine 继承 View,代码及说明如下:
1 | public class DynamicLine extends View { |
我们知道当 viewpager 切换时动作与 DynamicLine 的 startX 与 stopX 的具体对应关系。可以使用 ViewPager的addOnPageChangeListener() 方法:
1 | public MyOnPageChangeListener(Context context, ViewPager viewPager, DynamicLine dynamicLine, ViewPagerTitle viewPagerTitle, int allLength, int margin) { |
上面的方法主要是初始化操作,主要的计算及状态设置在OnPageChangeListener
监听中来操作:
1 |
|
与原文相比,我这里不再提供字体选中变大等效果,但是将结构进行了分解,方便拓展,毕竟每个人的需求不同,所以,这边不上传jcenter()
地址,直接上 github地址;
可以看到项目的目录结构:
1 | └── main |
而我们只需拷贝java -> sing -> flextitle
下的文件和res -> values -> attr.xml
到项目中即可,剩下的部分为自定义,可参照demo中的代码进行自己修改。