文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android怎么实现加载视差动画效果

2023-06-20 20:58

关注

本篇内容主要讲解“Android怎么实现加载视差动画效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android怎么实现加载视差动画效果”吧!

基础知识

继 Android实现旋转动画的两种方式 我们了解了 Android实现旋转的两种基本方法之后,我们来写一个综合案例

效果展示

Android怎么实现加载视差动画效果

代码实现 

实现思路

从效果中我们可以看到 可以将其分为三个动画:

旋转动画(Android实现旋转动画的两种方式)

聚合动画

扩展动画

代码展示

package com.wust.mydialog; import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;import android.view.WindowManager;import android.view.animation.AnticipateInterpolator;import android.view.animation.LinearInterpolator; import androidx.annotation.Nullable;  public class MyRotateView extends View {     //设置旋转间隔时间    private int SPLASH_CIRCLE_ROTATE_TIME = 1000;    //设置中心圆半径    private float CENTER_CIRCLE_RADIUS;    private float SMALL_CIRCLE_RADIUS;    private float mCurrentSingle = 0f;    private int[] mColorArray;    private Paint mCirclePaint;    private ValueAnimator va;    private Matrix mSpaceMatrix;     private LoadingState mLoadingState;    //当前中心圆半径    private float mCurCenterRadius;    private float mDiagonal;    private float mLineWidth;     public MyRotateView(Context context) {        super(context);    }     public MyRotateView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }     public MyRotateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }     @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int width = MeasureSpec.getSize(widthMeasureSpec);        int height = MeasureSpec.getSize(heightMeasureSpec);         //初始化参数        initParams(width, height);         setMeasuredDimension(width, height);    }     private void initParams(int w, int h) {        //设置中心圆半径        CENTER_CIRCLE_RADIUS = 1 / 4.0f * w;        //设置小圆的半径        SMALL_CIRCLE_RADIUS = 1 / 25.0f * w;        //获取小球颜色        mColorArray = getResources().getIntArray(R.array.splash_circle_colors);        //初始化画笔        mCirclePaint = new Paint();        mCirclePaint.setDither(true);        mCirclePaint.setAntiAlias(true);        //初始化旋转矩阵        mSpaceMatrix = new Matrix();    }     @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);                if (mLoadingState == null) {            mLoadingState = new RotateState();        }        mLoadingState.onDraw(canvas);    }     //定义 状态 抽象类    private abstract class LoadingState {        public abstract void onDraw(Canvas canvas);    }     //旋转动画    private class RotateState extends LoadingState {         public RotateState() {            //计算每个小球的间隔            double spaceAngle = 360.0d / mColorArray.length;            //初始化旋转矩阵            mSpaceMatrix.reset();            mSpaceMatrix.postRotate((float) spaceAngle, getWidth() / 2, getHeight() / 2);             va = ObjectAnimator.ofFloat(0f, 360.0f);            va.setDuration(SPLASH_CIRCLE_ROTATE_TIME);            va.setRepeatCount(ValueAnimator.INFINITE);            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    mCurrentSingle = (float) animation.getAnimatedValue();                    invalidate();                }            });            va.setInterpolator(new LinearInterpolator());            va.start();        }         @Override        public void onDraw(Canvas canvas) {            //绘制背景            canvas.drawColor(Color.WHITE);            //利用旋转画布法            canvas.save();            canvas.rotate(mCurrentSingle, getWidth() / 2, getHeight() / 2);            for (int i = 0; i < mColorArray.length; i++) {                canvas.concat(mSpaceMatrix);                //为 每个球 画笔 设置颜色                mCirclePaint.setColor(mColorArray[i]);                //利用旋转画布法                float cx = getWidth() / 2 + CENTER_CIRCLE_RADIUS;                float cy = getHeight() / 2;                 canvas.drawCircle(cx, cy, SMALL_CIRCLE_RADIUS, mCirclePaint);            }            canvas.restore();        }    }     //聚合动画    private class ScaleState extends LoadingState {         public ScaleState() {            va = ObjectAnimator.ofFloat(CENTER_CIRCLE_RADIUS,0);            va.setDuration(SPLASH_CIRCLE_ROTATE_TIME);            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    mCurCenterRadius = (float) animation.getAnimatedValue();                    invalidate();                }            });            va.addListener(new AnimatorListenerAdapter() {                @Override                public void onAnimationEnd(Animator animation) {                    mLoadingState = new ExtentState();                }            });            va.setInterpolator(new AnticipateInterpolator());            va.start();        }         @Override        public void onDraw(Canvas canvas) {            //绘制背景            canvas.drawColor(Color.WHITE);            //绘制小圆            canvas.save();            //这句话也不能调,要不然不连贯            canvas.rotate(mCurrentSingle,getWidth()/2,getHeight()/2);            for (int i = 0; i < mColorArray.length; i++) {                mCirclePaint.setColor(mColorArray[i]);                canvas.concat(mSpaceMatrix);                canvas.drawCircle(mCurCenterRadius+getWidth()/2,getHeight()/2,SMALL_CIRCLE_RADIUS,mCirclePaint);            }            canvas.restore();        }    }     //扩展动画    public class ExtentState extends LoadingState{         public ExtentState() {            //初始化对角线            float cx = getWidth()/2.0f;            float cy = getHeight()/2.0f;            mDiagonal = (float) Math.sqrt(Math.pow(cx,2)+Math.pow(cy,2));             va = ObjectAnimator.ofFloat(mDiagonal,0);            va.setDuration(3000);            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    mLineWidth = (float) animation.getAnimatedValue();                    invalidate();                }            });            va.setInterpolator(new LinearInterpolator());            va.start();        }         @Override        public void onDraw(Canvas canvas) {            mCirclePaint.setColor(Color.WHITE);            mCirclePaint.setStrokeWidth(mLineWidth*2);//元的半径只会到达线宽的中间,所以要乘2            mCirclePaint.setStyle(Paint.Style.STROKE);            canvas.drawCircle(getWidth()/2,getHeight()/2,mDiagonal,mCirclePaint);        }    }     public void dismiss() {        if (mLoadingState instanceof RotateState){            //取消旋转值动画            va.cancel();            //创建缩放动画            mLoadingState = new ScaleState();            //刷新布局、可以写也可以不写//            invalidate();        }    }}

到此,相信大家对“Android怎么实现加载视差动画效果”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯