![](https://img.haomeiwen.com/i6855508/bc8467b214aa6184.gif)
具体思路就是继承了Tablayout 然后动的时候重新绘制一个三角在下边
/**
* 支持自定义下标,自定义tab宽度
* <p>
*
* @author 郭凯奇
* @date 2017/10/31 21:18.
*/
public class SlidingTabLayout extends TabLayout {
/**
* 自定义指示器
*/
private Bitmap mSlideIcon;
/**
* 滑动过程中指示器偏移量
*/
private int mTranslationX;
/**
* 指示器初始Y偏移量
*/
private int mInitTranslationY;
int[] textwidth;
LinearLayout mTabStrip;
private boolean ishave = false;
public boolean ishave() {
return ishave;
}
public void setIshave(boolean ishave) {
this.ishave = ishave;
}
public void setTabWidth(int[] tabWidth, LinearLayout mTabStrip) {
this.textwidth = tabWidth;
this.mTabStrip = mTabStrip;
initTranslationParams(mTabStrip);
}
public SlidingTabLayout(Context context) {
super(context);
}
public SlidingTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.mSlideIcon = BitmapFactory.decodeResource(getResources(), R.drawable.home_jiaobiao);
}
/**
* 重绘下标
*/
public void redrawIndicator(int position) {
mTranslationX = 0;
if (textwidth == null) {
invalidate();
return;
}
if (position == 0) {
mTranslationX = textwidth[position] / 2;
invalidate();
return;
}
for (int i = 0; i <= position; i++) {
mTranslationX += textwidth[i];
if (i == position) {
mTranslationX = mTranslationX - (textwidth[i] / 2);
}
}
invalidate();
}
@Override
public int getScrollIndicators() {
return super.getScrollIndicators();
}
public Field getmTabStrip() {
Class<?> tabLayout = TabLayout.class;
Field tabStrip = null;
try {
tabStrip = tabLayout.getDeclaredField("mTabStrip");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return tabStrip;
}
/**
* 绘制指示器
*/
@Override
protected void dispatchDraw(Canvas canvas) {
if (mSlideIcon == null) {
return;
}
if (ishave) {
canvas.save();
// 平移到正确的位置,修正tabs的平移量
Log.e("invaaaaaa", mTranslationX + "");
canvas.translate(mTranslationX - this.mSlideIcon.getWidth() / 2, 200);
canvas.drawBitmap(this.mSlideIcon, 0, 0, null);
canvas.restore();
super.dispatchDraw(canvas);
return;
}
canvas.save();
// 平移到正确的位置,修正tabs的平移量
Log.e("invaaaaaa", mTranslationX + "");
canvas.translate(mTranslationX - this.mSlideIcon.getWidth() / 2, this.mInitTranslationY);
canvas.drawBitmap(this.mSlideIcon, 0, 0, null);
canvas.restore();
super.dispatchDraw(canvas);
}
/**
* 初始化三角下标的坐标参数
*/
private void initTranslationParams(LinearLayout llTab) {
if (mSlideIcon == null) {
return;
}
tabWidth = textwidth[0];
View firstView = llTab.getChildAt(0);
if (firstView != null) {
this.mInitTranslationY = (getBottom() - getTop() - this.mSlideIcon.getHeight());
this.mTranslationX = textwidth[0] / 2;
invalidate();
}
}
}
然后反射修改长度什么的
public class TabLayoutUtil {
//Slidingtablayout的专属适配器
public static void slidingScrol(final Context context, final SlidingTabLayout tabLayout) {
tabLayout.post(new Runnable() {
@Override
public void run() {
try {
//拿到tabLayout的mTabStrip属性
Field mTabStripField = tabLayout.getmTabStrip();
mTabStripField.setAccessible(true);
Log.d("setIndicatorWidth", "mTabStripField:" + mTabStripField);
LinearLayout mTabStrip = (LinearLayout) mTabStripField.get(tabLayout);
int dp10 = dip2px(context,10);
int[] textwidth = new int[mTabStrip.getChildCount()];
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
View tabView = mTabStrip.getChildAt(i);
//拿到tabView的mTextView属性
Field mTextViewField = tabView.getClass().getDeclaredField("mTextView");
mTextViewField.setAccessible(true);
TextView mTextView = (TextView) mTextViewField.get(tabView);
//因为我想要的效果是 字多宽线就多宽,所以测量mTextView的宽度
int width = 0;
width = mTextView.getWidth();
if (width == 0) {
mTextView.measure(0, 0);
width = mTextView.getMeasuredWidth();
}
Log.d("setIndicatorWidth", "mTextView.width:" + width);
//设置tab左右间距为10dp 注意这里不能使用Padding 因为源码中线的宽度是根据 tabView的宽度来设置的
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
params.width = width;
Log.d("setIndicatorWidth", "tabView.width:" + params.width);
params.leftMargin = dp10;
params.rightMargin = dp10;
tabView.setLayoutParams(params);
tabView.invalidate();
textwidth[i]=width+dp10+dp10;
tabView.setPadding(0, dip2px(context,20), 0, 0);
}
tabLayout.setTabWidth(textwidth,mTabStrip);
} catch (NoSuchFieldException e) {
Log.d("setIndicatorWidth", "NoSuchFieldException:" + e.getMessage());
e.printStackTrace();
} catch (IllegalAccessException e) {
Log.d("setIndicatorWidth", "IllegalAccessException:" + e.getMessage());
e.printStackTrace();
}
}
});
}
private static int dip2px(Context context, float dipValue)
{
Resources r = context.getResources();
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dipValue, r.getDisplayMetrics());
}
}
topTabLayout = (SlidingTabLayout) findViewById(R.id.tablayout);
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new TabFragmentAdapter(fragments, strings, getSupportFragmentManager(), this));
topTabLayout.setupWithViewPager(viewPager);
topTabLayout.setTabTextColors(getResources().getColor(R.color.radiobutton), getResources().getColor(R.color.radiobuttonzhong));
TabLayoutUtil.slidingScrol(this, topTabLayout);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
topTabLayout.redrawIndicator(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
贴的这个代码是三角是不能滑动的,只会瞬移到下一个tab的中间
想滑动的滑需要在viewpager的onscroll方法里去做一些操作
留下来是为了防止我忘了
有想看 的联系我 我给demo
网友评论