Twitter的like动画安卓版 - 备选方案

2023-10-27

英文: Twitter’s like animation in Android - alternative
相关动画网址:http://frogermcs.github.io/twitters-like-animation-in-android-alternative/
更多动画网址:http://frogermcs.github.io/
作者来源:Miroslaw Stanek

小编自己遇到的问题:最近在研究一个Twitter的like动画安卓版,在任何手机上面都可以正常播放动画,只有在一个htc的手机上面,没有任何错误日志,动画播放不出来
操作:设置–》开发者选择–》高级选项–》动画,把动画的选项打开就好了。

不久前Twitter展示了具有现代感的心形动画-作为star图标的替代。


虽然实现这个动画最简单的方法是使用 Frame Animation ,但是我们尝试用更灵活的方法来实现-手动绘制并用属性动画。这篇文章只是概要,没有深入的技术细节

一:实现

我们将创建一个名叫LikeButtonView的view,它是一个由三个子view构成的FrameLayout- CircleView 显示星星图标下面的圆,ImageView (星星)以及代表按钮周围浮点的DotsView 。

CircleView


这个视图负责绘制星星图标下面的大圆。它本可以实现得更简单(通过xml ),但是这里我们应该考虑按钮下面的背景颜色。

我们在canvas上绘制圆的实现:

Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    tempCanvas.drawColor(0xffffff, PorterDuff.Mode.CLEAR);
    tempCanvas.drawCircle(getWidth() / 2, getHeight() / 2, outerCircleRadiusProgress * maxCircleSize, circlePaint);
    tempCanvas.drawCircle(getWidth() / 2, getHeight() / 2, innerCircleRadiusProgress * maxCircleSize, maskPaint);
    canvas.drawBitmap(tempBitmap, 0, 0, null);
}

先使用CLEAR 模式绘制颜色以清除canvas。然后根据给定的进度(各自的进度是独立的)绘制内外圆。

内圆使用这样定义的mask paint :

Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    maxCircleSize = w / 2;
    tempBitmap = Bitmap.createBitmap(getWidth(), getWidth(), Bitmap.Config.ARGB_8888);
    tempCanvas = new Canvas(tempBitmap);
}

我们需要完全透明,不然的话内圆就会显示窗口颜色。

对于那些眼睛机灵的人应该还注意到了另外一件事-我们的外圆颜色是基于当前进度而变化的。这是通过 ArgbEvaluator 类来完成,该类可以基于一个给定的因子在两个颜色之间变换:

private void updateCircleColor() {
    float colorProgress = (float) Utils.clamp(outerCircleRadiusProgress, 0.5, 1);
    colorProgress = (float) Utils.mapValueFromRangeToRange(colorProgress, 0.5f, 1f, 0f, 1f);
    this.circlePaint.setColor((Integer) argbEvaluator.evaluate(colorProgress, START_COLOR, END_COLOR));
}

三:DotsView


这个view将绘制浮动在星星图标周围的圆点。跟CircleView一样,它是使用onDraw()来做这件事的:

protected void onDraw(Canvas canvas) {
    drawOuterDotsFrame(canvas);
    drawInnerDotsFrame(canvas);
}

private void drawOuterDotsFrame(Canvas canvas) {
    for (int i = 0; i < DOTS_COUNT; i++) {
        int cX = (int) (centerX + currentRadius1 * Math.cos(i * OUTER_DOTS_POSITION_ANGLE * Math.PI / 180));
        int cY = (int) (centerY + currentRadius1 * Math.sin(i * OUTER_DOTS_POSITION_ANGLE * Math.PI / 180));
        canvas.drawCircle(cX, cY, currentDotSize1, circlePaints[i % circlePaints.length]);
    }
}

private void drawInnerDotsFrame(Canvas canvas) {
    for (int i = 0; i < DOTS_COUNT; i++) {
        int cX = (int) (centerX + currentRadius2 * Math.cos((i * OUTER_DOTS_POSITION_ANGLE - 10) * Math.PI / 180));
        int cY = (int) (centerY + currentRadius2 * Math.sin((i * OUTER_DOTS_POSITION_ANGLE - 10) * Math.PI / 180));
        canvas.drawCircle(cX, cY, currentDotSize2, circlePaints[(i + 1) % circlePaints.length]);
    }
}

圆点是基于currentProgress绘制的,背后是数学逻辑,老实说从安卓sdk的角度来看这里没有什么有趣的地方,倒是有两个跟数学相关的东西:

圆点分布在一个圆上-它们的位置决定于:

int cX = (int) (centerX + currentRadius1 * Math.cos(i * OUTER_DOTS_POSITION_ANGLE * Math.PI / 180));

int cY = (int) (centerY + currentRadius1 * Math.sin(i * OUTER_DOTS_POSITION_ANGLE * Math.PI / 180));

意味着:在每个 OUTER_DOTS_POSITION_ANGLE 上设置圆点 (51 度).

每个圆点都有它自己的颜色动画:

private void updateDotsPaints() {
    if (currentProgress < 0.5f) {
        float progress = (float) Utils.mapValueFromRangeToRange(currentProgress, 0f, 0.5f, 0, 1f);
        circlePaints[0].setColor((Integer) argbEvaluator.evaluate(progress, COLOR_1, COLOR_2));
        circlePaints[1].setColor((Integer) argbEvaluator.evaluate(progress, COLOR_2, COLOR_3));
        circlePaints[2].setColor((Integer) argbEvaluator.evaluate(progress, COLOR_3, COLOR_4));
        circlePaints[3].setColor((Integer) argbEvaluator.evaluate(progress, COLOR_4, COLOR_1));
    } else {
        float progress = (float) Utils.mapValueFromRangeToRange(currentProgress, 0.5f, 1f, 0, 1f);
        circlePaints[0].setColor((Integer) argbEvaluator.evaluate(progress, COLOR_2, COLOR_3));
        circlePaints[1].setColor((Integer) argbEvaluator.evaluate(progress, COLOR_3, COLOR_4));
        circlePaints[2].setColor((Integer) argbEvaluator.evaluate(progress, COLOR_4, COLOR_1));
        circlePaints[3].setColor((Integer) argbEvaluator.evaluate(progress, COLOR_1, COLOR_2));
    }
}

这意味着圆点颜色在3个区间形式的值之间动画。我们再一次使用ArgbEvaluator 让它平滑。其余就很简单了
CircleView完整代码

package com.loveta.umengexample;

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

Twitter的like动画安卓版 - 备选方案 的相关文章

随机推荐

  • 数据库系统之NoSQL数据库系统

    NoSQL Database Systems 什么是NoSQL数据库系统 为什么使用NoSQL NoSQL数据库系统的属性 半结构化的 无模式的数据模型 专业分布模型 弱一致性 Relaxing durability Versioning
  • 操作系统_03_内存管理(个人总结)

    声明 1 本文为我的个人复习总结 并非那种从零基础开始普及知识 内容详细全面 言辞官方的文章 2 由于是个人总结 所以用最精简的话语来写文章 3 若有错误不当之处 请指出 为什么要有虚拟地址 使各个进程使用的内存 相互独立 单片机没有操作系
  • 论文笔记之DPG

    原论文地址 阅读DPG的必要性 A2C的难收敛使得policy based向着DDPG发展 而DDPG Deep DPG 因此想要理解DDPG算法 就必须先理解DPG Deterministic Policy Gradient Algori
  • 【QT5 带参connect语法记录】

    QT5 带参connect语法记录 slot版 lamda版 Qt4版 未测试 更多细节参考 slot版 void QListWidget itemClicked2 QListWidgetItem QListWidget itemClick
  • 第三章作业

    例3 1 在一个班级中随机抽取9名学生 得到每名学生的英语考试分数如下 91 69 75 78 81 96 92 88 86 计算9名学生的平均考试分数 解 根据式3 1有 x 91 69 75 78 81 96 92 88 86 9 84
  • 动态生成多个 React createRef

    有这么个需求 从接口获取数据 数据格式为 dataList 接口获取的数据 tableData 表格数据 const dataList tableData1 tableData2 tableData3 需要实现的效果大概长这样 dataLi
  • 【学习SLAM】Bundle Adjustment 光束法平差详解

    首先引述来自维基百科的定义 假设我们有一个3D空间中的点 他被位于不同位置的多个摄像机看到 那么所谓的光束法平差 Bundle Adjustment 就是能够从这些多视角信息中提取出3D点的坐标以及各个摄像机的相对位置和光学信息的过程 可能
  • C++ future async promise 用法详解 - shared_future

    shared future 文章目录 shared future 获得方式 作用 区别 原理 基本函数 基本用法 获得方式 只能由 future 得到 作用 同 future 区别 可以多线程 多次访问 shared state 原理 sh
  • C++分糖果

    题目背景 TDOG为大家准备了很多糖果作为节日礼物 由小T负责发放 题目描述 但是糖果被分开装在 nn 个袋子中 每个袋子里的糖果数量不一定相同 糖果一共要分发给 kk 个小伙伴 为了公平起见 发放给每个小伙伴的糖果数量要一致 小T想给小伙
  • 什么是LAMP?LAMP有什么优势?

    什么是LAMP LAMP 是指Linux 操作系统 Apache HTTP 服务器 MySQL 数据库 和 PHP 网络编程语言 一般用来建立 web 应用平台 和 Java J2EE 架构相比 LAMP 具有 Web 资源丰富 轻量 快速
  • 用Python完成毫秒级抢单,助你秒杀淘宝大单

    目录 引言 环境 需求分析 前期准备 淘宝购物流程回顾 秒杀的实现 代码梳理 总结 0 引言 年中购物618大狂欢开始了 各大电商又开始了大力度的折扣促销 我们的小胖又给大家谋了一波福利 淘宝APP直接搜索 小胖发福利 每天领取三次粉丝专属
  • Golang去除字符串前后空格

    v EthName strings Trim v EthName 两种方法都可以 v EthName strings TrimSpace v EthName
  • Python报错: python setup.py egg_info" failed with error code 1

    Python报错 Command python setup py egg info failed with error code 1 in private var folders 0m 7s1flm9j03d35pkr92jcsv3w000
  • 【PyTorch】torch.Tensor详解和常用操作

    学习教材 动手学深度学习 PYTORCH 版 DEMO https github com ShusenTang Dive into DL PyTorch PDF 制作by Marcus Yang https github com cheny
  • 排名第25位!众享比特连续两年上榜“北京民营企业中小百强”

    2022年9月26日 2022北京民营企业百强发布会成功召开 北京市工商业联合会发布了2022北京民营企业百强 1 4 榜单 北京众享比特科技有限公司连续两年荣登 北京民营企业中小百强榜单 排名前进57位 位列第25位 2022年 全市共有
  • 【AutoHotkey】 解析并执行 字符串中的 函数表达式

    预期效果 str func1 123 456 ExecFunc str 实现方式 正则文本解析出函数名及其参数 array形式 执行 该函数与其参数 难点
  • linux fseek函数用法详解

    1 功 能 重定位流 数据流 文件 上的 文件内部位置 指针 注意 不是 定位文件指针 文件指针指向文件 流 位置 指针指向文件内部的字节位置 随着文件的读取会移动 文件指针如果不重新赋值将不会改变指向别的文件 2 用 法 int fsee
  • JS算法之动态规划

    如果不能避免被剥削的命运 就要提高自己被剥削的价值 大家好 我是柒八九 今天 我们继续探索JS算法相关的知识点 我们来谈谈关于动态规划的相关知识点和具体的算法 如果 想了解其他数据结构的算法介绍 可以参考我们已经发布的文章 如下是算法系列的
  • MFC CPropertySheet控件

    步骤一 新建一个对话框 步骤二 新建三个属性页对话框资源 IDD PROPPAGE LARGE 并对新建的三个属性页对话框生成三个类 基类为CPropertyPage 步骤三 插入一个新的类 用于创建属性表单 基类为CPropertyShe
  • Twitter的like动画安卓版 - 备选方案

    英文 Twitter s like animation in Android alternative 相关动画网址 http frogermcs github io twitters like animation in android al