SAKA'S BLOG

ViewPager之自定义标签的使用

这篇算是自定义viewgroup的第一篇文章

PagerTitleStrip

ViewPager有一个功能是添加标签,也就是PagerTitleStrip.先来看一下官方文档:

1
2
3
4
java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.support.v4.view.PagerTitleStrip

PagerTitleStrip是ViewPager的当前页面,下一个页面和前一页面的非交互式指示器。它在XML布局中作为ViewPager的子视图。Android:layout_gravity设置为TOP或BOTTOM,可以将标签固定到ViewPager的顶部或底部。 每个页面的标题由提供给ViewPager的adapter中的getPageTitle(int)方法提供。

PagerTabStripPagerTitleStrip的一个子类,它可以为用户提供交互式的体验。

PagerTitleStrip构造方法

  1. PagerTitleStrip (Context context)
    用于在java代码中直接使用.
  2. PagerTitleStrip (Context context, AttributeSet attrs)
    用于在xml文件中使用.

getTextSpacing方法

返回一个int类型的值,表示两个title之间所需的距离,用像素作为单位.
在未设置setTextSpacing方法时,它会生成一个自动的值来平均分配三个标签,让每个当前显示的标签的前一个和后一个都完全显示在屏幕内.

setTextSpacing方法

设置标签之前的间隔距离,此处应传入一个int值,单位为像素.
此方法对应getTextSpading方法.

Note:当你设置的数值小于当前自适应的数值时,将会忽略你设置的数值而采用显示三个完全的标签.

setGravity方法

设置标签当中的文字在标签栏的位置,这个只能使用Gravity中的垂直方向的方法.

setNonPrimaryAlpha方法

设置非当前显示的标签页的透明度.
传入的值是一个float类型,取值范围是0-1.

PagerTabStrip

PagerTabStrip是PagerTitleStrip的一个子类.

1
2
3
4
5
java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.support.v4.view.PagerTitleStrip
↳ android.support.v4.view.PagerTabStrip

它的用法和PagerTitleStrip基本一致,只是它可以和用户产生交互,当你点击标签的前一页或者后一页时,可以跳到对应的页面.

构造方法

  1. PagerTabStrip (Context context)
    用于java代码中编写
  2. PagerTabStrip (Context context,AttributeSet attrs)
    用于xml布局中文件编写

boolean getDrawFullUnderline ()和void setDrawFullUnderline (boolean drawFull)和void setTabIndicatorColorResource (int resId)

前边方法返回后边方法的设置值.为设置的情况下默认返回true,会绘制这个下划线.

int getTabIndicatorColor ()和void setTabIndicatorColor (int color)

设置当前显示标签的指示器的颜色,是一个16进制数字.这个颜色UnderLine时一个颜色.

void setBackgroundColor (int color)和void setBackgroundResource (int resId)

设置整个标签的背景颜色.

看一下结果:

这些方法都相对简单,但是官方提供的都只是入门的方法,现在我们需要为它定制实现两个最简单那的功能:

  1. 设置当前选中页面的tab颜色高亮
  2. 设置当前选中页面的tab文字扩大

这两个功能并没有改变PagerTabStrip的结构,只是增加了一些特殊的设定.那我们可以继续使用原来的一些属性,增加自己设置的属性来达到实现上述两个要求.

首先要分析PagerTitleStrip的结构.

一个PagerTitleStrip的显示部分被平均分为三个部分(不设置textspace的情况下),第一个指示前一页的页面(假如当前页时第一页,则显示为空),中间的一个指示当前页面(当前页面始终处在这个位置),最后一个显示为下一个页面(若没有下一个页面的时候则显示为空).

实际上我们需要的是改变当前的标签的设置,而不需要改变其他,那么我们就可以自定义一个类继承自PagerTabStrip,目的时增加交互效果,然后设置两个属性:currentColorcurrentSize,就基本完成了我们的项目.

新增自定义属性

在values文件下新增自定义属性,让用户可以通过xml布局文件来控制新的属性:

1
2
3
4
<declare-styleable name="TabView">
<attr name="currentColor" format="color|reference" />
<attr name="currentSize" format="dimension|reference" />
</declare-styleable>

currentColor代表当前标签文本的高亮颜色,currentSize代表当标签文字显示的大小.

新建自定义类

新建自定义类TabView继承自PagerTabStript,继承构造方法.

1
2
3
4
5
6
7
8
9
public TabView(Context context) {
super(context);
init(context, null);
}

public TabView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}

然后获取自定义属性的值:

1
2
3
4
5
6
private void init(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TabView);
currentTabSize = ta.getDimension(R.styleable.TabView_currentSize, 20);
currentTabColor = ta.getColor(R.styleable.TabView_currentColor, Color.RED);
ta.recycle();
}

最后别忘记回收ta.

获取当前选中tab标签

通过前边的分析,我么可以知道,因为当前选中的标签始终处于中间一个,我们首先获取这个控件中的第二个textview,也就是position=1的位置.然后将我们的值赋给获取的textView.

1
2
3
4
5
6
7
private void setCurrentTab() {
viewPager = (ViewPager) getParent();
Log.d("tag", "currentIndex" + viewPager.getCurrentItem());
currentTab = (TextView) getChildAt(1);
currentTab.setTextSize(currentTabSize);
currentTab.setTextColor(currentTabColor);
}

暴露接口

更多的时候我们既想能从XML布局文件设置,又想能在java代码中设置属性,我们就可以暴露出这两个接口.

1
2
3
4
5
6
7
public void setCurrentTabColor(int currentTabColor) {
this.currentTabColor = currentTabColor;
}

public void setCurrentTabSize(float size) {
this.currentTabSize = size;
}

代码中的属性会覆盖XML布局文件中的属性.

下面看一下效果: