Android实现雅虎新闻摘要加载视差动画效果

基础知识 继 Android实现旋转动画的两种方式 我们了解了 Android实现旋转的两种基本方法之后,我们来写一个综合案例
效果展示 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); } @Overrideprotected 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(); } @Overrideprotected 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() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mCurrentSingle = (float) animation.getAnimatedValue(); invalidate(); }}); va.setInterpolator(new LinearInterpolator()); va.start(); } @Overridepublic 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() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mCurCenterRadius = (float) animation.getAnimatedValue(); invalidate(); }}); va.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {mLoadingState = new ExtentState(); }}); va.setInterpolator(new AnticipateInterpolator()); va.start(); } @Overridepublic 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() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mLineWidth = (float) animation.getAnimatedValue(); invalidate(); }}); va.setInterpolator(new LinearInterpolator()); va.start(); } @Overridepublic void onDraw(Canvas canvas) {mCirclePaint.setColor(Color.WHITE); mCirclePaint.setStrokeWidth(mLineWidth*2); //元的半径只会到达线宽的中间,所以要乘2mCirclePaint.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视觉动画内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读