基础知识

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

效果展示

代码实现 

实现思路

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

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

2、聚合动画

3、扩展动画

代码展示

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;  /** * ClassName: com.wust.mydialog.MyRotateView 
* Description:
* date: 2021/8/7 12:13
* * @author yiqi
* @QQ 1820762465 * @微信 yiqiideallife * @技术交流QQ群 928023749 */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实现雅虎新闻摘要加载视差动画效果的文章就介绍到这了,更多相关android视觉动画内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

更多相关文章

  1. Android(安卓)动画之Lottie动画使用
  2. Android(安卓)动画之Lottie动画使用
  3. android 图片旋转
  4. android 模仿 弹性菜单
  5. Android控件抖动效果
  6. android动画效果
  7. Android(1.5及以上版本) 开机图片/文字/动画分析
  8. Android(安卓)ListView动画实现方法
  9. android:动态缩放和旋转图像

随机推荐

  1. sqlserver数据库优化解析(图文剖析)
  2. 自增长键列统计信息的处理方法
  3. 如何在SQL Server中使用随机记录集
  4. 如何在SQL Server 2014中用资源调控器压
  5. SQL Server把某个字段的数据用一条语句转
  6. SQL Server根据分区表名查找所在的文件及
  7. SQL Server中使用Trigger监控存储过程更
  8. SQL Server查询数据库中表使用空间信息实
  9. SQL Server中通配符的使用示例
  10. SQL语句实现查询当前数据库IO等待状况