Android自定义控件之自定义歌词显示控件

直接上图片和代码
请添加图片描述


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"
        />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值