preface
In recent development, the effect of text color gradient was implemented. What, text color gradient, too? I don’t like it, but I can only say ok…
Let’s start with the final image
Normal operation
There are two common ways to do this, and the principle is the same. Both create a LinearGradient object and set it into the TextView’s brush.
So let’s take a look at the LinearGradient
LinearGradient
Shader subclass, used to implement linear gradient effects. Common constructors are as follows
public LinearGradient(float x0,
float y0,
float x1,
float y1,
int color0,
int color1,
Shader.TileMode tile)
Copy the code
Parameters that
- (x0, y0) : coordinates of the start point of the gradient
- (x1, y1) : coordinates of the end of the gradient
- Color0: gradient start color
- Color1: Gradient terminates color
- Tile: Fill mode
- CLAMP: edge stretching. Fill the range outside the region with the edge color
- -Leonard: I don’t want to REPEAT myself. Repeat the filling in both horizontal and vertical directions
- MIRROR: MIRROR mode. The filling is repeated in a mirror image in both horizontal and vertical directions, with gaps between adjacent images
Practice a
Inherit TextView, override onLayout method and set Shader
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)); }}}Copy the code
LinearGradient is created with a starting coordinate of (0,0) and a ending coordinate of (getWidth(), getHeight()), so the gradient gradient is from the top left to the bottom right. Results the following
getPaint().setShader(new LinearGradient(0.0.0, getHeight(),
startColor,
endColor,
Shader.TileMode.CLAMP));
Copy the code
Results the following
Approach 2
Set Shader directly
Shader shader = new LinearGradient(0.0.0, textView.getLineHeight(),
Color.RED, Color.BLUE, Shader.TileMode.REPEAT);
textView.getPaint().setShader(shader);
textView.setText("Hello benio\n Hello Benio \n Hello Benio");
Copy the code
Results the following
SAO operation
To make part of the text color different, the first thing I thought of was Span. Take a look at the official 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) {
// This is where I changed the colortextPaint.setColor(mColor); }}Copy the code
As you can see, the key is the updateDrawState() method. We can implement the desired style within this method. Next, we refer to the practice of ForegroundColorSpan and follow the idea of practice 2 above to achieve a gradient color 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)); }}Copy the code
The test code
SpannableString part1 = new SpannableString("Hello,");
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("Hello, Benio \n Hello, Benio");
part2.setSpan(new LinearGradientForegroundSpan(Color.RED, Color.LTGRAY, textView.getLineHeight()),
0, part2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.append(part2);
textView.setText(sb);
Copy the code
Results the following
class ShaderForegroundSpan extends CharacterStyle implements UpdateAppearance {
private Shader mShader;
public ShaderForegroundSpan(Shader shader) {
mShader = shader;
}
@Override
public void updateDrawState(TextPaint tp) { tp.setShader(mShader); }}Copy the code
summary
Text color gradient works by creating a LinearGradient object and then setting it into the TextView’s brush. Different parameters of constructing LinearGradient will result in different gradient effects
- Method 1: The gradient effect is related to the width or height of the View. Applies to all scenes where text has an overall gradient
- Method 2: The gradient effect is related to the row, each row has the same gradient effect. Suitable for scenes where each line of text has the same gradient effect
- Practice three: use Span to achieve, suitable for local text gradient, multi-line text gradient scene
reference
- How to Create a Gradient TextView in Android
- Text with gradient in Android