先看效果
观察底部导航栏的变化,在滑动过程中,文字的颜色随着滑动完成的百分比来显示,底部的文本很像TextView,但是原生的TextView没有颜色变化百分比这一属性,所以需要自定义View去实现。所以图中显示的效果需要实现,用到自定义View、ViewPager和Fragment。整体布局就是上方ViewPager,下方LinearLayout,下方LinearLayout嵌套多个自定义View。本文主要讲自定义View的部分,实现一个能够变化颜色的View。
思路:先用A画笔绘制文本(图中黑色字体部分),再用B画笔绘制变色区域(图中紫色部分),它们是一个底层和顶层的关系,相当于A绘制的内容被B绘制的内容覆盖了(其实应该只用一只画笔就可以搞定)。
一、创建自定义View
案例中的效果和TextView类似,所以直接继承TextView,可以省下很多时间。
public class ColorChangeTextView extends androidx.appcompat.widget.AppCompatTextView {
public ColorChangeTextView(@NonNull Context context) {
super(context);
}
public ColorChangeTextView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ColorChangeTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
构造函数中参数的说明参考之前写的自定义View实战学习(一)
二、创建与使用自定义属性
三、获取自定义属性的值
自定义View实战学习(一)参考自定义View实战学习(一) ,一样的用法,这里不多赘述
四、测量onMeasure()
由于是继承TextView,所以没必要自己再去测量,想要了解的参考自定义View实战学习(一)
五、绘制onDraw()
1、初始化画笔
用到两只画笔,画底色和画顶色,只是颜色的区别。所以直接封个方法,返回画笔对象。
private Paint getBasePaint(int color) {
Paint paint = new Paint();
paint.setColor(color);
paint.setAntiAlias(true);
paint.setTextSize(50);
return paint;
}
2、画底层颜色的文字
用到canvas的drawText(String text,float x,float y,Paint paint)方法
text:要绘制的文本
x:到x轴的距离(原点在左上角)
y:基线到y轴的距离(基线是什么?自定义View实战学习(一))
paint:画笔
// 1.画底层不变色的text
Rect rectBase = new Rect();
mColorBasePaint.getTextBounds(getText().toString(), 0, getText().length(), rectBase);
canvas.drawText(getText().toString(),
getWidth() / 2 - rectBase.width() / 2,
(fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom + getHeight() / 2,
mColorBasePaint);
3、画顶层颜色的文字
顶层的颜色是一个随着百分比的,所以不需要绘制整个文本,用到Rect(int left,int top,int right,int bottom),绘制某个区域。还需要判断文字颜色的变化是从左往右还是从右往左。
Rect rect;
if (isLeftToRight) {
rect = new Rect(0, 0, (int) (getWidth() * percent), getHeight());
} else {
rect = new Rect((int)((1-percent) * getWidth()), 0, getWidth(), getHeight());
}
canvas.clipRect(rect);
mColorChangePaint.getTextBounds(getText().toString(), 0, getText().length(), rect);
canvas.drawText(getText().toString(),
getWidth() / 2 - rect.width() / 2,
(fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom + getHeight() / 2,
mColorChangePaint);