您的位置:首页 > 其它

自定义个TabLayout

2016-03-09 14:47 309 查看
先来个图

两个的


多个的


布局

<com.rsd.library.widget.RTabLayout
android:layout_width="wrap_content"
app:tabTextSize="20sp"
app:tabRadius="10dp"
app:tabBorderColor="#0000ff"
app:tabBorderWidth="1dp"
app:tabMenus="AAA,BBB"
android:layout_height="wrap_content" />


本来说圆角地方都不一样,先是写了一个用path实现的,不过那样计算起来太麻烦。就想改成用xfermode的了,先画个圆角rect,在前面画几个rect就可以了。

代码

public class RTabLayout extends View {
private Paint paint;
private RectF rect;
private RectF rect2;
private Xfermode xfermode;
private String[] menus;
private RectF[] rects;
private float perWidth;

private int index;
private int radius;
private int borderWidth;
private int borderColor;
private int selectColor;
private int unSelectColor;
private int dividedColor;
private int textSize;

private float touchSlop;
private float startX = 0;
private float startY = 0;
private double distance = 0;
private int touchIndex;

private boolean drawLine;

private OnItemClickListener onItemClickListener;

public RTabLayout(Context context) {
this(context, null);
}

public RTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public RTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RTabLayout, defStyleAttr, 0);
radius = array.getDimensionPixelSize(R.styleable.RTabLayout_tabRadius, 30);
borderWidth = array.getDimensionPixelSize(R.styleable.RTabLayout_tabBorderWidth, 5);
borderColor = array.getColor(R.styleable.RTabLayout_tabBorderColor, 0xffffffff);
selectColor = array.getColor(R.styleable.RTabLayout_tabSelectColor, 0xffffffff);
unSelectColor = array.getColor(R.styleable.RTabLayout_tabUnSelectColor, 0xffffa417);
dividedColor = array.getColor(R.styleable.RTabLayout_tabDividedColor, 0xffffffff);
textSize = array.getDimensionPixelSize(R.styleable.RTabLayout_tabTextSize, 30);
String menu = array.getString(R.styleable.RTabLayout_tabMenus);
if (menu == null) {
menus = new String[]{"A", "B"};
} else {
menus = menu.split(",");
}
setMenus(menus);
array.recycle();
init();
}

private void init() {
touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTextSize(textSize);
rect = new RectF();
rect2 = new RectF();
xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
rect.set(0, 0, w, h);
rect2.set(borderWidth, borderWidth, w - borderWidth, h - borderWidth);
perWidth = w / rects.length;
for (int i = 0; i < rects.length; i++) {
rects[i] = new RectF(i * perWidth, 0, (i + 1) * perWidth, h);
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int w = 0, h = 0;
if (widthMode == MeasureSpec.EXACTLY) {
w = widthSize;
} else {
int maxLen = 0;
for (int i = 0; i < menus.length; i++) {
if (menus[i].length() > maxLen) {
maxLen = menus[i].length();
}
}
w = textSize * (maxLen + 2) * menus.length;
}
if (heightMode == MeasureSpec.EXACTLY) {
h = heightSize;
} else {
h = textSize * 2;
}
setMeasuredDimension(w, h);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawBg(canvas);
drawLine(canvas);
drawText(canvas);
}

private void drawBg(Canvas canvas) {
paint.setColor(borderColor);
canvas.drawRoundRect(rect, radius, radius, paint);
int layer = canvas.saveLayer(rect, paint, Canvas.ALL_SAVE_FLAG);
canvas.drawRoundRect(rect2, radius, radius, paint);
paint.setXfermode(xfermode);
for (int i = 0; i < rects.length; i++) {
if (i == index) {
paint.setColor(selectColor);
} else {
paint.setColor(unSelectColor);
}
canvas.drawRect(rects[i], paint);
}
paint.setXfermode(null);
canvas.restoreToCount(layer);
}

private void drawLine(Canvas canvas) {
if (drawLine) {
return;
}
paint.setColor(dividedColor);
for (int i = 1; i < menus.length; i++) {
if (i == index || i == index + 1) {
continue;
}
float x = perWidth * i;
float h = rect.height();
canvas.drawLine(x, h * 0.2f, x, h * 0.8f, paint);
}
drawLine = true;
}

private void drawText(Canvas canvas) {
float x;
float y;
for (int i = 0; i < menus.length; i++) {
if (i == index) {
paint.setColor(unSelectColor);
} else {
paint.setColor(selectColor);
}
x = perWidth * (i + 0.5f) - paint.measureText(menus[i]) / 2;
y = rect.height() / 2 - (paint.descent() + paint.ascent()) / 2;
canvas.drawText(menus[i], x, y, paint);
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
touchIndex = (int) (startX / perWidth);
break;
case MotionEvent.ACTION_MOVE:
distance = Math.sqrt((event.getX() - startX) * (event.getX() - startX) + (event.getY() - startY) * (event.getY() - startY));
break;
case MotionEvent.ACTION_UP:
if (distance < touchSlop) {
setCurrent(touchIndex);
if (onItemClickListener != null) {
onItemClickListener.onItemClick(touchIndex);
}
}
distance = 0;
break;
}
return true;
}

public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}

public void setMenus(String[] menus) {
this.menus = menus;
rects = new RectF[menus.length];
}

public void setCurrent(int position) {
this.index = position;
invalidate();
}

public interface OnItemClickListener {
void onItemClick(int position);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: