最近開發過程當中要實現文本顏色漸變的效果。什麼,文本顏色也要漸變?雖然不樂意,可是也只能說好吧...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 的參數不一樣,漸變效果也不同