一娶牌、問題背景
在我們實(shí)際卡法需求中可能會要修改tablayout下方的indicator的樣式與屬性,比如indicator的長度鹤盒,或者給tablayout加個(gè)背景但是需要indicator滑動的效果国章,然而原生的tablayout卻僅僅提供了tablayout的height即厚度的屬性,自定義化的程度很低芙盘。
二驯用、問題探索
通過查閱源碼,發(fā)現(xiàn)tablayout的下劃線是由其內(nèi)部類SlidingTabStrip實(shí)現(xiàn)何陆,其繼承自LinearLayout布局的viewgroup晨汹。源碼如下
private class SlidingTabStrip extends LinearLayout {
private int mSelectedIndicatorHeight;
private final Paint mSelectedIndicatorPaint;
int mSelectedPosition = -1;
float mSelectionOffset;
private int mLayoutDirection = -1;
private int mIndicatorLeft = -1;
private int mIndicatorRight = -1;
private ValueAnimator mIndicatorAnimator;
SlidingTabStrip(Context context) {
super(context);
setWillNotDraw(false);
mSelectedIndicatorPaint = new Paint();
}
...
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
// Thick colored underline below the current selection
if (mIndicatorLeft >= 0 && mIndicatorRight > mIndicatorLeft) {
canvas.drawRect(mIndicatorLeft, getHeight() -
mSelectedIndicatorHeight,mIndicatorRight,
getHeight(), mSelectedIndicatorPaint);
}
}
省略部分細(xì)節(jié)代碼,查看其ondraw方法會發(fā)現(xiàn)其繪制過程和三個(gè)變量相關(guān):mSelectedIndicatorHeight贷盲,mIndicatorLeft 和mIndicatorRight 淘这,由于mSelectedIndicatorHeight有提供接口可以改變可忽略,實(shí)際控制其繪制過程的為剩下倆個(gè)變量巩剖。
三铝穷、問題解決方案
正如上述縮分析的,控制SlidingTabStrip的繪制過程的為mIndicatorLeft 和mIndicatorRight 倆個(gè)變量佳魔,這倆個(gè)變量同時(shí)也是控制其位置顯示的變量曙聂,只要獲取到這倆個(gè)變量其實(shí)就可以進(jìn)行我們自定義Indicator的封裝,那么如何獲取這倆個(gè)變量呢鞠鲜?——反射
//自定義drawable
public class IndicatorDrawable extends Drawable{
View view;
Paint paint;
float paddingLeft;
float paddingTop;
public IndicatorDrawable(View view) {
this.view = view;
paint = new Paint();
paint.setColor(Color.parseColor("#0f0"));
float density = view.getResources().getDisplayMetrics().density;
//這兩個(gè)留白可以根據(jù)需求更改
paddingLeft = 0 * density;
paddingTop = 5 * density;
}
@Override
public void draw(@NonNull Canvas canvas) {
//自定義背景
int mIndicatorLeft = getIntValue("mIndicatorLeft");
int mIndicatorRight = getIntValue("mIndicatorRight");
int height = view.getHeight();
int radius = height / 2;
if (mIndicatorLeft >= 0 && mIndicatorRight > mIndicatorLeft) {
//canvas.drawRoundRect(new RectF(mIndicatorLeft + (int)paddingLeft, (int)paddingTop, mIndicatorRight - (int)paddingLeft, height - (int)paddingTop), radius, radius, paint);
//縮減indicator的寬度
canvas.drawRect(mIndicatorLeft+40, height - 4,
mIndicatorRight-40, height, paint);
}
}
int getIntValue(String name) {
try {
Field f = view.getClass().getDeclaredField(name);
f.setAccessible(true);
Object obj = f.get(view);
return (Integer) obj;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
@Override
public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.UNKNOWN;
}
}