欢迎访问宙启技术站
智能推送

怎么在Android中使用SurfaceView实现一个点赞动画

发布时间:2023-05-16 05:51:50

SurfaceView是Android中的一个视图组件,可以在其上面绘制2D或3D图形。在使用SurfaceView实现点赞动画时,我们可以通过绘制动画的各个帧来达到动画效果。以下是实现一个点赞动画的步骤:

1. 创建自定义的SurfaceView,并在其构造函数中初始化画笔等绘制工具。

2. 重写SurfaceView的surfaceCreated()方法,在其中获取SurfaceHolder对象,并开启一个新线程执行动画绘制任务。

3. 在绘制线程中实现点赞动画的逻辑,包括每个帧的绘制和动画效果的实现。具体来说,我们可以通过绘制各种图形来实现点赞动画,例如:绘制一个圆点,按照特定的路径绘制拖动的手势,绘制一个心形图案等。

4. 在动画结束后,通过回调机制通知外部代码动画已经结束。

以下是一个简单的点赞动画实现的代码示例:

public class LikeView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder mHolder;
    private Paint mPaint;
    
    private boolean mIsRunning;
    private boolean mIsLiking;
    
    public LikeView(Context context) {
        super(context);
        init();
    }

    public LikeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public LikeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mHolder = getHolder();
        mHolder.addCallback(this);
        
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.RED);
        
        mIsRunning = true;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        new Thread(new AnimationRunnable(holder)).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // do nothing
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mIsRunning = false;
    }
    
    public void startLikeAnimation() {
        mIsLiking = true;
    }
    
    public boolean isLiking() {
        return mIsLiking;
    }

    private class AnimationRunnable implements Runnable {

        private final SurfaceHolder mHolder;
        
        private int mRadius;
        private int mX;
        private int mY;
        private int mStepsLeft;
        
        public AnimationRunnable(SurfaceHolder holder) {
            mHolder = holder;
            
            mRadius = 0;
            mX = 0;
            mY = 0;
            mStepsLeft = 0;
        }

        @Override
        public void run() {
            while (mIsRunning) {
                Canvas canvas = mHolder.lockCanvas();
                
                if (canvas != null) {
                    if (mIsLiking) {
                        drawLikeAnimation(canvas);
                    } else {
                        canvas.drawColor(Color.WHITE);
                    }
                    
                    mHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
        
        private void drawLikeAnimation(Canvas canvas) {
            // 绘制圆点
            canvas.drawCircle(mX, mY, mRadius, mPaint);
            
            // 绘制手势路径
            Path path = new Path();
            path.moveTo(mX, mY);
            path.lineTo(mX + 50, mY + 30);
            path.lineTo(mX + 100, mY - 20);
            canvas.drawPath(path, mPaint);
            
            // 绘制心形
            int heartSize = mRadius / 2;
            canvas.drawArc(mX - heartSize / 2, mY - heartSize / 2, mX + heartSize / 2, mY + heartSize / 2, -225, 225, false, mPaint);
            canvas.drawArc(mX - heartSize / 2, mY - heartSize / 2, mX + heartSize / 2, mY + heartSize / 2, -45, 225, false, mPaint);
            canvas.drawRect(mX - heartSize / 2, mY - heartSize / 2, mX, mY, mPaint);
            canvas.drawRect(mX, mY - heartSize / 2, mX + heartSize / 2, mY, mPaint);
            
            // 更新状态
            if (mStepsLeft == 0) {
                mX = (int) (Math.random() * canvas.getWidth());
                mY = (int) (Math.random() * canvas.getHeight());
                mRadius = 0;
                mStepsLeft = 20;
                
                // 通知外部代码动画已经结束
                if (!mIsLiking) {
                    mStepsLeft = 0;
                }
            } else {
                mRadius += 10;
                mStepsLeft--;
            }
        }
    }
}

在实现过程中,我们通过一个mIsLiking变量来记录当前是否需要执行点赞动画,然后在绘制线程中根据这个变量的值来判断是否需要绘制动画。具体来说,当mIsLiking为true时,我们就会在绘制线程中执行点赞动画的逻辑;当mIsLiking为false时,我们就只会在绘制线程中执行清空画布的逻辑,从而实现动画的停止效果。

实现完毕后,外部代码就可以通过调用startLikeAnimation()方法来触发点赞动画效果,而通过调用isLiking()方法可以获取当前是否正在执行点赞动画。