看到很多的APP,都有PagerSlidingTab这个控件,而且风格都不一样,所以我决定研究一番。
1.老师给了个控件PagerSlidingTab,假如Tab只有2个的时候,标题并没有占满全屏。那怎改?
2.如果想要有自己的效果,那么就得理解源码,修改源码。
源码怎么看:不可能全部看完,抓住主要的,自己关心的地方。否则看源码就是一件痛苦的事情。
1)首先看PagerSlidingTab这个类的继承关系,发现它继承自HorizontalScrollView
-->FrameLayout-->ViewGroup。
2)看PagerSlidingTab构造函数,会发现标题其实是水平的LinearLayout,源码中用
tabsContainer表示。
3)我想,标题没有居中,也就是子View没有添加权重。于是Ctrl + F,在类里搜索tabsContainer。
发现addTextTab和addIconTab两个方法中tabsContainer会有添加子View,于是Ctrl + F,再搜索
addTextTab方法,找到方法在哪里被调用。
1
2
3
4
5
6
7
8
9
|
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());
}
}
|
发现和ViewPager的适配器有关,而平常我们会使用PagerAdapter,所以addTextTab 会被调用。
4)于是在 addTextTab 方法添加子View的时候为子View添加了权重
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
private
void
addTextTab(
final
int
position, String title) {
TextView tab =
new
TextView(getContext());
tab.setText(title);
tab.setFocusable(
true
);
tab.setGravity(Gravity.CENTER);
tab.setSingleLine();
//我给子View添加的权重
tab.setLayoutParams(
new
LinearLayout.LayoutParams(
0
,LayoutParams.MATCH_PARENT,
1
.0f));
tab.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
pager.setCurrentItem(position);
}
});
tabsContainer.addView(tab);
}
|
5)但是遗憾的是,运行结果还是一个样。那怎么办?
后来在onMeasure方法中发现了惊天大秘密:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
@Override
protected
void
onMeasure(
int
widthMeasureSpec,
int
heightMeasureSpec) {
super
.onMeasure(widthMeasureSpec, heightMeasureSpec);
if
(!shouldExpand || MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED) {
return
;
}
int
myWidth = getMeasuredWidth();
int
childWidth =
0
;
for
(
int
i =
0
; i < tabCount; i++) {
childWidth += tabsContainer.getChildAt(i).getMeasuredWidth();
}
if
(!checkedTabWidths && childWidth >
0
&& myWidth >
0
) {
if
(childWidth <= myWidth) {
for
(
int
i =
0
; i < tabCount; i++) {
tabsContainer.getChildAt(i).setLayoutParams(expandedTabLayoutParams);
}
}
checkedTabWidths =
true
;
}
}
|
发现在此方法里其实就是对我所说的这个问题的控制,shouldExpand 就是控制标题是否平均分配
而这个属性在XML或者set方法里都可以设置。默认是false,不会平均分配。
虽然绕来绕去,改个属性就能解决问题,但还是收获不少。
3.PagerSlidingTab的其他属性
<declare-styleable name="PagerSlidingTab">
<attr name="indicatorColor" format="color" /> 指针也就是滑动块的颜色
<attr name="underlineColor" format="color" /> 滑动条与View之间那条线颜色
<attr name="underlineHeight" format="dimension" /> 滑动条与View之间那条线高度
<attr name="dividerColor" format="color" /> 滑动块之间竖直分隔线
<attr name="indicatorHeight" format="dimension" /> 滑动块的高度
<attr name="pst_dividerPadding" format="dimension" />
<attr name="tabPaddingLeftRight" format="dimension" />
<attr name="scrollOffset" format="dimension" />
<attr name="tabBackground" format="reference" />
<attr name="shouldExpand" format="boolean" /> 导航条是否平均分配宽度
<attr name="pst_textAllCaps" format="boolean" />
</declare-styleable>
还有和字体颜色和大小相关的属性,并没有写在attrs.xml中,不过可以通过set方法进行设置,上面
的属性也都有对应的set方法。
源码中
1
|
tab.setTextColor(i==
0
?getResources().getColor(R.color.slidingtab_indicatorcolor):tabTextColor);
|
就是设置字体的颜色,即当前导航条字体颜色与其它导航条字体颜色。
另外有一点让人费解的就是导航条的背景色怎么设置的?
1
|
app:tabBackground=
"@color/gray"
|
只要给导航条添加了背景色,下面的滑动块就不显示了,求路过的帮忙解答一下啊?
本文转自屠夫章哥 51CTO博客,原文链接:http://blog.51cto.com/4259297/1707011,如需转载请自行联系原作者