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

 更新时间:2021年08月09日 17:36:52   作者:我想月薪过万  
这篇文章主要介绍了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 <br/>
 * Description: <br/>
 * date: 2021/8/7 12:13<br/>
 *
 * @author yiqi<br />
 * @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视觉动画内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • android:TextView简单设置文本样式和超链接的方法

    android:TextView简单设置文本样式和超链接的方法

    这篇文章主要介绍了android:TextView简单设置文本样式和超链接的方法,涉及TextView常见文字属性的相关操作技巧,需要的朋友可以参考下
    2016-08-08
  • 横竖屏切换导致页面频繁重启screenLayout解析

    横竖屏切换导致页面频繁重启screenLayout解析

    这篇文章主要为大家介绍了横竖屏切换导致页面频繁重启screenLayout解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Android控件实现图片缩放功能

    Android控件实现图片缩放功能

    这篇文章主要介绍了Android控件实现对图片进行缩放功能的相关资料,需要的朋友可以参考下
    2018-01-01
  • Android短信备份及数据插入实现代码解析

    Android短信备份及数据插入实现代码解析

    这篇文章主要介绍了Android短信备份及数据插入实现代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Android开发之开发者头条(一)启动页实现

    Android开发之开发者头条(一)启动页实现

    这篇文章主要介绍了Android开发之开发者头条(一)启动页实现的相关资料,需要的朋友可以参考下
    2016-04-04
  • Android开发中TextView文本过长滚动显示实现方法分析

    Android开发中TextView文本过长滚动显示实现方法分析

    这篇文章主要介绍了Android开发中TextView文本过长滚动显示实现方法,结合实例形式分析了Android项目开发中TextView显示超长文本的具体操作技巧与注意事项,需要的朋友可以参考下
    2018-02-02
  • Android:“万能”Activity重构篇

    Android:“万能”Activity重构篇

    本文主要介绍了mvp以及每一层,以及使用mvp来重构“万能”Activity,其实每一层需要注意的东西还有很多,比如model层是最难写的一层。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • Android12四大组件之Activity生命周期变化详解

    Android12四大组件之Activity生命周期变化详解

    虽然说我们天天都在使用Activity,但是你真的对Activity的生命机制完全了解了吗?Activity的生命周期方法只有七个,但是其实那只是默认的情况。也就是说在其他情况下,Activity的生命周期可能不会是按照我们以前所知道的流程,本章着重讲解Activity的生命周期变化
    2022-07-07
  • Android App开发中ViewPager组件的入门使用教程

    Android App开发中ViewPager组件的入门使用教程

    这篇文章主要介绍了Android App开发中ViewPager组件的入门使用教程,ViewPager主要用来实现通过滑动来切换页面的效果,需要的朋友可以参考下
    2016-03-03
  • Android开发实现的Intent跳转工具类实例

    Android开发实现的Intent跳转工具类实例

    这篇文章主要介绍了Android开发实现的Intent跳转工具类,简单描述了Intent组件的功能并结合实例形式给出了页面跳转、拍照、图片调用等相关操作技巧,需要的朋友可以参考下
    2017-11-11

最新评论