目前市场上面存在很多的Tab导航指示器,但是大多数都是与ViewPager关系紧密的,原生的TabLayout等无法满足拆分的需求,所以自己定制一个可以左右滑动的Tab指示器。
1.继承HorizontalScrollView
HorizontalScrollView我们都知道是一个横向滑动的ScrollView,我们可以利用这个特性来定制我们的控件。步骤:
(1)动态的创建一个LinearLayout填充到HorizontalScrollView里面
(2)动态的网这个LinearLayout里面添加TextView
(3)设置点击状态的改变和给tab添加选中的点击接口回调
2.详情请看代码
(1)动态的创建一个LinearLayout填充到HorizontalScrollView里面
/**
* 初始化容纳tab的线性容器
*/
private void initLinearLayout() {
if (mLinearLayout == null) {
mLinearLayout = new LinearLayout(getContext());
}
mLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
addView(mLinearLayout, new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
}
(2)动态的生成TextView并设置相关属性,添加到LinearLayout里面
/**
* 设置tab的标题内容
*
* @param titles
*/
public void setTabTitles(List<String> titles) {
mLinearLayout.removeAllViews();
for (int i = 0; i < titles.size(); i++) {
TextView tv = getTextView(titles, i);
mLinearLayout.addView(tv);
}
setOnItemClick();
setTabSelect(0); //默认选中的tab
}
@NonNull
private TextView getTextView(List<String> titles, int i) {
String text = titles.get(i);
TextView tv = new TextView(getContext());
tv.setGravity(Gravity.CENTER);
tv.setText(text);
tv.setTextColor(mTextColor);
tv.setPadding(0, dpTopx(12), 0, dpTopx(12));
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSize);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
layoutParams.setMargins(dpTopx(12), 0, dpTopx(12), 0);
tv.setLayoutParams(layoutParams);
return tv;
}
(3)滑动tab并且改变tab选中的状态
private void changeTab(final int j, final View childView) {
if (mRunnable != null) {
removeCallbacks(mRunnable);
}
mRunnable = new Runnable() {
@Override
public void run() {
resetTextViewColor();
highLightTextView(j);
final int scrollPos = childView.getLeft() - (getWidth() - childView.getWidth()) / 2;
smoothScrollTo(scrollPos, 0); //改变选中的tab的位置
}
};
post(mRunnable);
}
改变字体的颜色,主要是遍历每一个TextView,重新设置他们的颜色和状态
/**
* 重置字体的颜色
*/
public void resetTextViewColor() {
int childCount = mLinearLayout.getChildCount();
for (int i = 0; i < childCount; i++) {
TextView childView = (TextView) mLinearLayout.getChildAt(i);
childView.setTextColor(mTextColor);
childView.setBackgroundResource(0);
}
}
/**
* 改变选中的tab的字体的颜色
*
* @param position
*/
public void highLightTextView(int position) {
TextView childView = (TextView) mLinearLayout.getChildAt(position);
childView.setTextColor(mTextColorSelect);
childView.setBackgroundResource(R.drawable.selector_shape_blue_line_bg);
}
3.使用
使用的时候特别简单,直接引用到布局当中,并且设置一些属性,关于自定义属性,这里就不多说,大家可以自行百度,内容特别的多。
<declare-styleable name="CommonIndicator">
<!--tab默认的字体颜色-->
<attr name="text_color" format="color"/>
<!--tab选中的字体颜色-->
<attr name="text_color_select" format="color"/>
<!--tab字体的大小-->
<attr name="text_size" format="integer"/>
</declare-styleable>
然后找到后直接使用就行了
String[] texts = {"詹姆斯", "韦德", "史密斯", "汤普森","勒夫","托马斯","欧文"};
CommonIndicator indicator = (CommonIndicator) findViewById(R.id.indicator);
indicator.setTabTitles(Arrays.asList(texts));