最近开发过程当中要实现文本颜色渐变的效果。什么,文本颜色也要渐变?虽然不乐意,可是也只能说好吧...java
先来点最终效果图 android
常见的渐变作法有两种,原理其实都是同样的。都是建立一个 LinearGradient 对象,并将其设置到 TextView 的画笔中。app
先来简单介绍下 LinearGradientide
Shader 子类,用于实现线性渐变的效果。经常使用的构造方法以下测试
public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile) 复制代码
参数说明ui
继承 TextView,重写 onLayout 方法后设置 Shaderthis
public class GradientTextView extends TextView {
...
@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(),
startColor,
endColor,
Shader.TileMode.CLAMP));
}
}
}
复制代码
建立 LinearGradient 时,传入的起始坐标为 (0,0),结束坐标为 (getWidth(), getHeight()),因此渐变效果是从左上角向右下角渐变的。效果以下 spa
getPaint().setShader(new LinearGradient(0, 0, 0, getHeight(),
startColor,
endColor,
Shader.TileMode.CLAMP));
复制代码
效果以下 3d
直接设置 Shadercode
Shader shader = new LinearGradient(0, 0, 0, textView.getLineHeight(),
Color.RED, Color.BLUE, Shader.TileMode.REPEAT);
textView.getPaint().setShader(shader);
textView.setText("哈喽,benio\n哈喽,benio\n哈喽,benio");
复制代码
效果以下
要实现部分文字颜色不同的话,第一时间我想到的是 Span。先看下官方提供的 ForegroundColorSpan
public class ForegroundColorSpan extends CharacterStyle implements UpdateAppearance, ParcelableSpan {
private final int mColor;
public ForegroundColorSpan(@ColorInt int color) {
mColor = color;
}
...
/** * Updates the color of the TextPaint to the foreground color. */
@Override
public void updateDrawState(@NonNull TextPaint textPaint) {
// 就是这里改了颜色
textPaint.setColor(mColor);
}
}
复制代码
能够看到,关键就是 updateDrawState() 方法。咱们能够在该方法内实现想要的样式。接下来咱们参考 ForegroundColorSpan 的作法,依照上面作法二的思路,实现一个渐变色的 Span
class LinearGradientForegroundSpan extends CharacterStyle implements UpdateAppearance {
private int startColor;
private int endColor;
private int lineHeight;
public LinearGradientForegroundSpan(int startColor, int endColor, int lineHeight) {
this.startColor = startColor;
this.endColor = endColor;
this.lineHeight = lineHeight;
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setShader(new LinearGradient(0, 0, 0, lineHeight,
startColor, endColor, Shader.TileMode.REPEAT));
}
}
复制代码
测试代码
SpannableString part1 = new SpannableString("哈喽,");
part1.setSpan(new LinearGradientForegroundSpan(Color.RED, Color.LTGRAY, textView.getLineHeight()),
0, part1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableStringBuilder sb = new SpannableStringBuilder();
sb.append(part1);
sb.append("benio\n");
SpannableString part2 = new SpannableString("哈喽,benio\n哈喽,benio");
part2.setSpan(new LinearGradientForegroundSpan(Color.RED, Color.LTGRAY, textView.getLineHeight()),
0, part2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.append(part2);
textView.setText(sb);
复制代码
效果以下
class ShaderForegroundSpan extends CharacterStyle implements UpdateAppearance {
private Shader mShader;
public ShaderForegroundSpan(Shader shader) {
mShader = shader;
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setShader(mShader);
}
}
复制代码
文本颜色渐变的原理都是经过建立一个 LinearGradient 对象,而后其设置到 TextView 的画笔中实现的。构造 LinearGradient 的参数不一样,渐变效果也不同