说明
Android开发过程中,对TextView操作是无时不刻的操作,字体颜色控制又是这里最常见的操作之一。常见的布局文件直接设置字体颜色,或者普通的setColor方法就不介绍了,这里记录一下渐变色LinearGradient的一些基础用法。
LinearGradient常用构造函数
LinearGradient通常用于控制TextView字体中的渐变颜色,主要有2个构造方法:
1,LinearGradient(float x0, float y0, float x1, float y1,@ColorInt int color0, @ColorInt int color1,@NonNull TileMode tile);
2,LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors,@Nullable float[] positions, @NonNull TileMode tile)
LinearGradient常用构造函数,参数说明
参数说明:
x0:表示渐变的起始点x坐标;
y0:表示渐变的起始点y坐标;
x1:表示渐变的终点x坐标;
y1:表示渐变的终点y坐标;
colors:表示渐变的颜色数组;
positions:用来指定颜色数组的相对位置;
color0: 表示渐变开始颜色;
color1: 表示渐变结束颜色;
tile:表示平铺方式
Shader.TileMode说明
Shader.TileMode有3种参数可供选择,分别为CLAMP、REPEAT和MIRROR:
1,CLAMP:如果渲染器超出原始边界范围,则会复制边缘颜色对超出范围的区域进行着色;
2,REPEAT:在横向和纵向上以平铺的形式重复渲染位图;
3,MIRROR:在横向和纵向上以镜像的方式重复渲染位图
其他注意说明
注意:通常,参数positions设为null,表示颜色数组以斜坡线的形式均匀分布
用法示例1
继承 TextView,重写 onLayout 方法后设置 Shader,也可再ondraw中处理
public class GradientTextView1 extends AppCompatTextView {
private int mStartColor;
private int mEndColor;
private boolean mBold;
public GradientTextView1(@NonNull Context context) {
this(context, null);
}
public GradientTextView1(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public GradientTextView1(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
TypedArray typedArray =
context.obtainStyledAttributes(attrs, R.styleable.GradientTextView);
if (typedArray == null) {
return;
}
mBold = typedArray.getBoolean(R.styleable.GradientTextView_gradient_bold,
false);
mStartColor =
typedArray.getColor(R.styleable.GradientTextView_gradient_start_color,
getResources().getColor(R.color.primary_color));
mEndColor =
typedArray.getColor(R.styleable.GradientTextView_gradient_end_color,
getResources().getColor(R.color.accent_color));
typedArray.recycle();
if (mBold) {
getPaint().setFakeBoldText(true);
}
}
@SuppressLint("DrawAllocation")
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
getPaint().setShader(new LinearGradient(0, 0, getWidth(), getHeight(),
mStartColor,
mEndColor,
Shader.TileMode.CLAMP));
}
}
}
用法示例2
自定一个工具方法,在代码中动态改变
public class TextViewUtil {
public static void setTextColorGradient(TextView textView, @ColorRes int startColor, @ColorRes int endColor) {
if (textView == null || textView.getContext() == null) {
return;
}
Context context = textView.getContext();
@ColorInt final int sc = context.getResources().getColor(startColor);
@ColorInt final int ec = context.getResources().getColor(endColor);
final float x = textView.getPaint().getTextSize() * textView.getText().length();
LinearGradient gradient = new LinearGradient(0, 0, x, 0, sc, ec, Shader.TileMode.CLAMP);
textView.getPaint().setShader(gradient);
textView.invalidate();
}
public static void setTextColorGradient(TextView textView, int[] colors, float[] positions) {
if (textView == null || textView.getContext() == null) {
return;
}
String text = textView.getText().toString();
// 方法1:getTextBounds
Rect rect = new Rect();
textView.getPaint().getTextBounds(text, 0, text.length(), rect);
// 方法2:measureText
// float measuredWidth = textView.getPaint().measureText(text);
float textWidth = rect.width();
LinearGradient linearGradient = new LinearGradient(0, 0, textWidth, 0,
colors,
positions,
Shader.TileMode.REPEAT);
textView.getPaint().setShader(linearGradient);
textView.invalidate();
}
public static void clearTextColorGradient(TextView textView) {
textView.getPaint().setShader(null);
textView.invalidate();
}
用法示例3
借鉴Span做法,自定义一个Span;也可直接写个Span,在代码中再去用
<declare-styleable name="GradientTextView">
<attr name="gradient_text" format="string" />
<attr name="gradient_bold" format="boolean" />
<attr name="gradient_start_color" format="color" />
<attr name="gradient_end_color" format="color" />
</declare-styleable>
public class GradientTextView extends AppCompatTextView {
private String mGradientText;
private int mStartColor;
private int mEndColor;
private boolean mBold;
public GradientTextView(@NonNull Context context) {
this(context, null);
}
public GradientTextView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public GradientTextView(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
TypedArray typedArray =
context.obtainStyledAttributes(attrs, R.styleable.GradientTextView);
if (typedArray == null) {
return;
}
mGradientText =
typedArray.getString(R.styleable.GradientTextView_gradient_text);
mBold = typedArray.getBoolean(R.styleable.GradientTextView_gradient_bold,
false);
mStartColor =
typedArray.getColor(R.styleable.GradientTextView_gradient_start_color,
getResources().getColor(R.color.primary_color));
mEndColor =
typedArray.getColor(R.styleable.GradientTextView_gradient_end_color,
getResources().getColor(R.color.accent_color));
typedArray.recycle();
setGradientText(mGradientText);
if (mBold) {
getPaint().setFakeBoldText(true);
}
}
public void setGradientText(String text) {
if (text == null || text.length() == 0) {
return;
}
SpannableString spannableString = new SpannableString(text);
GradientFontSpan gradientFontSpan = new GradientFontSpan(mStartColor, mEndColor);
spannableString.setSpan(gradientFontSpan, 0, text.length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
setText(spannableString);
invalidate();
}
public static class GradientFontSpan extends ReplacementSpan {
private int mSize;
private int mStartColor;
private int mEndColor;
public GradientFontSpan(int startColor, int endColor) {
mStartColor = startColor;
mEndColor = endColor;
}
public GradientFontSpan(Context context) {
mStartColor = context.getResources().getColor(R.color.primary_color);
mEndColor = context.getResources().getColor(R.color.accent_color);
}
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end,
@Nullable Paint.FontMetricsInt fm) {
mSize = Math.round(paint.measureText(text, start, end));
Paint.FontMetricsInt metrics = paint.getFontMetricsInt();
if (fm != null) {
fm.top = metrics.top;
fm.ascent = metrics.ascent;
fm.descent = metrics.descent;
fm.bottom = metrics.bottom;
}
return mSize;
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x,
int top, int y, int bottom, @NonNull Paint paint) {
LinearGradient gradient = new LinearGradient(0, 0, mSize, 0, mEndColor, mStartColor,
Shader.TileMode.CLAMP);
paint.setShader(gradient);
canvas.drawText(text, start, end, x, y, paint);
}
}
}
网友评论