视差动画 - 雅虎新闻摘要加载

2023-11-05

基础知识

继 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();
        }
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

视差动画 - 雅虎新闻摘要加载 的相关文章

  • 使用正则表达式验证电子邮件的最大长度

    我找到了用于电子邮件验证的正则表达式 a z0 9 a z0 9 a z0 9 a z0 9 a z 2 4 我希望电子邮件的最大长度为 20 个字符 因此我将其更改为 a z0 9 a z0 9 a z0 9 a z0 9 a z 2 4
  • 递归取消 allOf CompletableFuture

    如果我有 CompletableFuture
  • 始终将双精度舍入

    我怎么总是能把一个double to an int 并且永远不要将其四舍五入 我知道Math round double 但我希望它始终向上舍入 所以如果是的话3 2 四舍五入为 4 您可以使用Math ceil method 请参阅Java
  • 在约束验证器中使用 Guice 进行依赖注入

    我有一个在 ConstraintValidator 的实现中注入类的用例 我正在使用 Google guice 进行依赖项注入 目前无法在验证器内注入 我的场景的简化形式 内部模块 Provides Singleton public Ser
  • 如何在捆绑中存储稀疏数组

    我有一个SparseArray
  • javadoc 子集/java 库组织

    我自己从来没有运行过javadoc 无论是在命令行还是ant 的 javadoc 任务 http ant apache org manual Tasks javadoc html 我将使用 ant 我需要为我编写的库生成 javadoc 问
  • 在 Eclipse RCP 应用程序中禁用插件贡献

    我经常遇到这个问题 但尚未找到解决方案 每当我编写一个新的基于 Eclipse RCP 的应用程序并包含来自 Eclipse 平台的插件时 我都会 继承 其中一些插件的 UI 贡献 大多数贡献 菜单项 键盘快捷键 属性页 都很有用 但有时我
  • 如何在 JASPIC 中保存经过身份验证的用户?

    我开发了一个安全认证模块 SAM 并实现了validateRequest方法 我还有一个简单的 Web 应用程序配置为使用此 SAM In my validateRequest方法 我检查 clientSubject 并设置一个Caller
  • 添加 char 和 int

    据我了解 字符是一个字符 即一个字母 一个digit 标点符号 制表符 空格或类似的东西 因此 当我这样做时 char c 1 System out println c 输出 1 正是我所期望的 那么为什么当我这样做时 int a 1 ch
  • log4j.properties 在 Wildfly 上无法正常工作

    我的类路径中有一个 log4j properties 文件 它位于 APP XX jar log4j properties 位置 我注意到在ear文件中我还可以在lib文件夹中找到log4j 1 2 17 jar 但无论我在 log4j p
  • 谷歌地图URL中参数的含义是什么

    我正在 Android 上使用 Webkit 浏览器 我想在以下 URL 中获得一个红色 A 符号
  • 如何更改 JAX-WS Web 服务的地址位置

    我们目前已经公开了具有以下 URL 的 JAX RPC Web 服务 http xx xx xx xx myservice MYGatewaySoapHttpPort wsdl http xx xx xx xx myservice MYGa
  • 如何在不使用 -cp 开关的情况下在 Groovy 中自动加载数据库 jar?

    我想简化调用 Oracle 数据库的 Groovy 脚本的执行 如何将 ojdbc jar 添加到默认类路径以便我可以运行 groovy RunScript groovy 代替 groovy cp ojdbc5 jar RunScript
  • 为什么/何时应该使用泛型方法?

    学习Java的时候遇到过通用方法 public
  • Android 模拟器提示和技巧 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • junit4 使用特定测试方法创建测试套件

    在 junit4 中 我想执行来自不同类的特定测试方法 即想要使用来自不同类的特定测试方法创建一个测试套件 假设我有两门课 public class Test Login Test public void test Login 001 Sy
  • 亚马逊 Linux - 安装 openjdk-debuginfo?

    我试图使用jstack在 ec2 实例上amazon linux 所以我安装了openjdk devel包裹 sudo yum install java 1 7 0 openjdk devel x86 64 但是 jstack 引发了异常j
  • Axis2 的 wsdl2java 在 RPC/Encoded 样式 Web 服务上失败

    Axis2 有替代方案吗 或者让它工作的方式 例如不同的数据绑定 Retrieving document at Exception in thread main org apache axis2 wsdl codegen CodeGener
  • Android 可扩展列表视图随机播放子项

    你好 我正在使用 Android Expandable listview 并用不同的视图在其中膨胀子视图 我遇到的问题是 当我展开视图然后打开另一个父视图时 布局中的子视图会变得混乱并在代码中膨胀错误的布局 这是我的两个项目的示例代码 这是
  • MyBatis 枚举的使用

    我知道以前有人问过这个问题 但我无法根据迄今为止找到的信息实施解决方案 所以也许有人可以向我解释一下 我有一个表 状态 它有两列 id 和 name id是PK 我不想使用 POJO Status 而是使用枚举 我创建了这样一个枚举 如下所

随机推荐

  • IDEA自动生成类和方法注释

    效果图 一 类注释 1 创建 2 向header文件中添加内容 author 作者 create YEAR MONTH DAY HOUR MINUTE Description 3 class文件关联header配置 4 使用方法 创建类时候
  • 话题:程序员酒后吐真言,竟然这样说

    据说 美国最大的论坛 Reddit 最近有一个热帖 一个程序员说自己喝醉了 做了10年软件工程师 心里有好多话想说 我可能会后悔今天说了这些话 他洋洋洒洒写了一大堆 获得9700多个赞 其中有一条竟然是说 作为一名工程师 最被低估的技能是记
  • 数据结构与算法之图的广度优先遍历

    数据结构与算法之图的广度优先遍历 前要 图的广度优先遍历 树 VS 图 树的层序遍历 图 广度优先遍历 代码实现图广度优先遍历 方法说明 代码示例 算法存在的问题 算法复杂度分析 邻接矩阵存储的图 邻接表存储的图 广度优先生成树 广度优先生
  • 2023年第三届控制理论与应用国际会议

    会议简介 Brief Introduction 2023年第三届控制理论与应用国际会议 ICoCTA 2023 会议时间 2023年10月20 22日 召开地点 中国 厦门 大会官网 www icocta org 控制理论作为一门科学技术
  • 两电源之间接0.1UF的电容起什么作用?

    应该起的是滤波的作用 1 高频滤波电容的配置 A 小于10个输出的小规模集成电路 工作频率 50MHz时 至少配接一个0 1 f的滤波电容 工作频率 50MHz时 每个电源引脚配接一个0 1 f的滤波电容 B 对于中大规模集成电路 每个电源
  • Oracle根据某个字段去重并查询出第一条数据

    表结构 要求 查询出无重复GLRDM的GLRDM GLRMC数据 SQL SELECT a GLRDM a GLRMC FROM SELECT b row number over partition BY GLRDM ORDER BY GL
  • idea只读模式(注释变为*)

    强迫症患者 习惯了idea的 注解 突然不小心点了idea的 注解 想要变回来的解决方式 idea注释突然变成不可编辑模式 此时可以调整Reader Mode 把Enable Reader mode取消即可 以上就是我对idea变为只读模式
  • Orange‘s:一个操作系统的实现学习笔记1

    安装虚拟机 bochs NASM 前言 一 安装虚拟机VMware和操作系统 安装Ubuntu 安装VMTools 1 提示直接安装 2 点击选项安装 安装后记 二 安装bochs和NASM 1 安装bochs 2 安装NASM 安装后记
  • Perl 函数参考

    Perl wait 函数 wait该函数等待子进程终止 返回已故进程的进程ID 进程的退出状态包含在 中 句法 以下是此函数的简单语法 wait 返回值 如果没有子进程 则此函数返回 1 否则将显示已故进程的进程ID Perl waitpi
  • JVM的运行时内存区域划分详细讲解

    文章目录 一 运行时数据区域 1 程序计数器 Program Counter Register 2 Java 虚拟机栈 Java Virtual Machine Stacks 3 本地方法栈 Native Method Stack 4 Ja
  • 【VirtualBox系列】VirtualBox设置虚拟机网络绝对详细

    前言知识 在学习配置网络之前 我们需要先了解下关于virtualBox的三种网络模式 搞懂虚拟机VirtualBox网络配置 需求分析 现在如何实现一种效果 我想达到主机可以访问虚拟机 并且虚拟机能够访问外网 还有如果我更换了路由器 之前配
  • Excel基础操作

    目录 第一节 新建Excel工作簿 第二节 认识Excel操作界面 第三节 上下文选项卡和自定义功能区 第四节 文件选项卡的设置 第五节 输入和编辑数据 第六节 数据的显示 第七节 数据输入技巧 第八节 填充与序列 第九节 填充选项 第十节
  • LVGL学习 stm32f407-board-lvgl v8.3移植

    LVGL学习 stm32f407 board lvglv8 3移植 移植过程有问题 请参考正点原子的教程或者视频 硬件平台 STM32F407ZGT6核心板 3 2寸屏幕 LVGL LVGL Light and Versatile Grap
  • CloudCompare 二次开发(3)——计算点云质心

    目录 一 概述 二 代码集成 三 结果展示 一 概述 不依赖任何第三方点云相关库 使用ClopudCompare计算点云质心 本文由CSDN点云侠原创 原文链接 爬虫网站自重 二 代码集成 1 mainwindow h文件public中添加
  • Python数据分析是什么?为什么要对比Excel学习

    Python本身是一门编程语言 应用于Web开发 爬虫 机器学习等多个领域 但是除了这些 今天小千要告诉你Python大热的一个学习方向 那就是Python数据分析 我常常会听到这样的问题 金融分析中 为什么我要学习像Python这样的编程
  • H5跳转微信小程序,通过获取URL Scheme,实现短信跳转小程序,微信跳转小程序,邮件跳转小程序,外部链接跳转小程序

    H5链接跳转小程序有2种方式 第一种 通过微信官方提供的标签wx open launch weapp 打开小程序 第二种 通过获取URL Scheme实现链接跳转小程序 一 wx open launch weapp 官方文档https de
  • java 读取word_java poi word读取

    用 poi 读取word文件 老是报错 org apache poi poifs filesystem NotOLE2FileException Invalid header signature read 0xC9D33C3A6D6F724
  • 期货开户的具体程序是什么?

    一 开户 1 对客户的条件要求 客户应至少具备以下条件 1 具有完全民事行为能力 2 有与进行期货交易相适应的自有资金或者其他财产 能够承担期货交易风险 3 有固定的住所 4 符合国家 行业的有关规定 二 保证金 中小投资者可以等待股指期货
  • tinyMCE编辑器去除换行增加的P标签

    tinyMCE编辑器去除换行增加的P标签 tinyMCE里使用回车后会加P标签 如何变成原本的br标签呢 搜索出force p newlines false参数可以关闭自动添加P标签 但实际测试没什么变化 查询了一下源码发现带 p 的就fo
  • 视差动画 - 雅虎新闻摘要加载

    基础知识 继 Android实现旋转动画的两种方式 我们了解了 Android实现旋转的两种基本方法之后 我们来写一个综合案例 效果展示 代码实现 实现思路 从效果中我们可以看到 可以将其分为三个动画 1 旋转动画 Android实现旋转动