Android 实现歌词文字逐渐高亮效果

该博客介绍了如何在Android中使用自定义视图MyTextView实现文字的高亮滚动效果。通过在底层绘制基础文字,再在上层绘制渐变的高亮部分,利用属性动画控制高亮区域的显示比例,从而达到滚动效果。主要涉及Canvas、Paint、ObjectAnimator等组件的使用。
摘要由CSDN通过智能技术生成

高亮滚动思路

Canvas是可以是有多层绘制效果组成的,我们可以现在底层绘制我们的基础文字效果,然后再上层绘制我们的高亮效果

package com.test.customview;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class MyTextView extends androidx.appcompat.widget.AppCompatTextView
{
    public MyTextView(@NonNull Context context)
    {
        super(context);
        init();
    }

    public MyTextView(@NonNull Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);
        init();
    }

    public MyTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
    }


    private Paint paint;
    private final String defaultText = "晏传利最爱你了";
    private float percent = 0.0f;

    private void init()
    {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(0XFF000000);
        paint.setTextSize(80);
        
        
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                
                //利用属性动画对效果进行设置
                ObjectAnimator.ofFloat(MyTextView.this,"percent",0,1).setDuration(5000).start();
            }
        }, 2000);

    }


    @Override
    protected void onDraw(Canvas canvas)
    {
        drawCenterX(canvas);
        drawCenterY(canvas);

        drawCenterText(canvas);
        drawCenterText1(canvas);
    }


    /**
     * 我们基础文字效果
     * 把文字绘制到View的中间位置,
     */
    private void drawCenterText(final Canvas canvas)
    {
        //  canvas.save();
        //.......  这中间是我们的canvas的一层画布
        // canvas.restore();

        //  canvas.save();
        //.......  这又是我们的canvas的领一层画布
        // canvas.restore();
        
        canvas.save();
        paint.setColor(0XFF000000);
        int viewHeight = getMeasuredHeight();
        int viewWidth = getMeasuredWidth();
        float textWidth = paint.measureText(defaultText);
        Paint.FontMetrics metrics = paint.getFontMetrics();
        float x = viewWidth / 2.0f - textWidth / 2;
        float y = viewHeight / 2 - (metrics.bottom + metrics.top) / 2;
        canvas.drawText(defaultText, x, y, paint);
        canvas.restore();
    }


    /**
     * 渐变文字效果-->其实也是绘制出全部的文字效果
     * 但是我们裁剪只显示出我们需要的部分
     * @param canvas
     */
    private void drawCenterText1(final Canvas canvas)
    {
        paint.setColor(0XFFFF6600);
        canvas.save();
        int viewHeight = getMeasuredHeight();
        int viewWidth = getMeasuredWidth();
        float textWidth = paint.measureText(defaultText);
        Paint.FontMetrics metrics = paint.getFontMetrics();
        float x = viewWidth / 2.0f - textWidth / 2;
        float y = viewHeight / 2 - (metrics.bottom + metrics.top) / 2;
        float left=x;
        float top=0;
        // 根据比例 从开始位置逐渐显示全部区域
        float right=x+textWidth*percent;
        float bottom=viewHeight;
        //利用裁剪功能 裁剪出我们需要的部分 
        RectF rect = new RectF(left,top,right,bottom);
        canvas.clipRect(rect);
        canvas.drawText(defaultText, x, y, paint);
        canvas.restore();
    }


    /**
     * 绘制中间X
     * @param canvas
     */
    private void drawCenterX(final Canvas canvas)
    {
        float viewHeight = getMeasuredHeight();
        float viewWidth = getMeasuredWidth();
        canvas.drawLine(viewWidth / 2.0f, 0.0f, viewWidth / 2.0f, viewHeight, paint);
    }

    /**
     * 绘制中间Y
     * @param canvas
     */
    private void drawCenterY(final Canvas canvas)
    {
        float viewHeight = getMeasuredHeight();
        float viewWidth = getMeasuredWidth();
        canvas.drawLine(0, viewHeight / 2, viewWidth, viewHeight / 2, paint);
    }

    public float getPercent()
    {
        return percent;
    }

    public void setPercent(float percent)
    {
        this.percent = percent;
        invalidate();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~搬~运~工~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值