直接上图片和代码
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.Gravity;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
public class GradientColorTextView extends AppCompatTextView {
private TextPaint mGradientPaint;
private long mAnimationDuration = 8000; // 默认动画时间为8秒
private float mGradientOffset = 0;
public GradientColorTextView(Context context) {
super(context);
init(null);
}
public GradientColorTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public GradientColorTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs) {
mGradientPaint = new TextPaint();
// 获取XML配置的textSize
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, new int[]{android.R.attr.textSize});
float textSize = a.getDimensionPixelSize(0, -1);
if (textSize != -1) {
mGradientPaint.setTextSize(textSize);
}
a.recycle();
}
// 启动颜色变化动画
startColorAnimation();
}
private void startColorAnimation() {
ValueAnimator colorAnimator = ValueAnimator.ofFloat(0, 1);
colorAnimator.setDuration(mAnimationDuration);
colorAnimator.addUpdateListener(animation -> {
mGradientOffset = (float) animation.getAnimatedValue();
invalidate(); // 重新绘制
});
colorAnimator.start();
}
@Override
protected void onDraw(Canvas canvas) {
int[] colors = {Color.GREEN,Color.BLACK};
float[] positions = {0, mGradientOffset};
String text=getText().toString();
Shader shader = new LinearGradient(
0, 0, getWidth(), 0,
colors, positions, Shader.TileMode.CLAMP);
Matrix matrix = new Matrix();
matrix.setTranslate(mGradientOffset * getWidth(), 0);
shader.setLocalMatrix(matrix);
mGradientPaint.setShader(shader);
//canvas.drawText(getText().toString(), 0, getTextSize(), mGradientPaint);
StaticLayout staticLayout = new StaticLayout(
text,
mGradientPaint,
getWidth(),
Layout.Alignment.ALIGN_NORMAL,
getLineSpacingMultiplier(),
getLineSpacingExtra(),
false);
// 计算绘制位置,以保留原有gravity属性
float x = 0;
float y = 0;
// 获取padding值
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
// 获取TextView的gravity属性
int gravity = getGravity();
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
y = getHeight() - staticLayout.getHeight();
}
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.CENTER_VERTICAL) {
y = (getHeight() - staticLayout.getHeight()) / 2;
}
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) {
x = paddingLeft;
}
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.RIGHT) {
x = getWidth()-paddingRight-mGradientPaint.measureText(text);
}
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.CENTER_HORIZONTAL ) {
x = (getWidth()-mGradientPaint.measureText(text))/2;
}
if ((gravity & Gravity.CENTER) == Gravity.CENTER ||gravity==Gravity.CENTER) {
x = (getWidth()-mGradientPaint.measureText(text))/2;
}
// 绘制文本
canvas.save();
canvas.translate(x, y);
staticLayout.draw(canvas);
canvas.restore();
}
public void setAnimationDuration(long duration) {
this.mAnimationDuration = duration;
// 重新启动颜色变化动画
startColorAnimation();
}
}
使用如下:
<com.test.GradientColorTextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="时间钾钠钾钠钾按摩网址吱吱吱吱哈哈年时候i是"
android:gravity="center"
android:textSize="30sp"
android:background="#a0000000"
/>