Android实现启动页倒计时效果
作者:龙旋 发布时间:2021-07-26 20:50:14
目录
开始准备
开始动画
画圆弧
项目使用
背景图
完整代码
今天介绍一个很简单的倒计时动画,仿酷狗音乐的启动页倒计时效果,也是大多数APP在用的一个动画,来看看效果图:
整体的思路就是用一个平滑的帧动画来画圆弧就行了。
这篇文章学到什么?
了解属性动画ValueAnimator的用法
了解动画属性插值Interpolator,让动画过度得更自然
如何画圆弧
开始准备
新建一个类继承TextView,因为中间还有跳过的文本,所以选择用TextView来画个动起来的背景图。
/**
* 倒计时文本
*/
@SuppressLint("AppCompatCustomView")
public class CountDownTextView extends TextView {
// 倒计时动画时间
private int duration = 5000;
// 动画扫过的角度
private int mSweepAngle = 360;
// 属性动画
private ValueAnimator animator;
// 矩形用来保存位置大小信息
private final RectF mRect = new RectF();
// 圆弧的画笔
private Paint mBackgroundPaint;
public CountDownTextView(Context context) {
this(context, null);
}
public CountDownTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CountDownTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
// 设置画笔平滑
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 设置画笔颜色
mBackgroundPaint.setColor(Color.WHITE);
// 设置画笔边框宽度
mBackgroundPaint.setStrokeWidth(5);
// 设置画笔样式为边框类型
mBackgroundPaint.setStyle(Paint.Style.STROKE);
}
}
开始动画
原理:利用圆的360度角来做属性动画,让它平滑的分配做每帧动画的角度值,然后调用invalidate()来重绘自己本身,从而进入到本身的onDraw()方法来画图。
/**
* 开始倒计时
*/
public void start() {
// 在动画中
if (mSweepAngle != 360) return;
// 初始化属性动画
animator = ValueAnimator.ofInt(mSweepAngle).setDuration(duration);
// 设置插值
animator.setInterpolator(new LinearInterpolator());
// 设置动画监听
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 获取属性动画返回的动画值
mSweepAngle = (int) animation.getAnimatedValue();
// 重绘自己
invalidate();
}
});
// 开始动画
animator.start();
}
画圆弧
画圆弧比较简单, 从效果图来看,有的同学可能刚开始以为要画两个圆,一个背景的内圆和一个白色边框的大圆,其实这里可以利用画笔设置画笔样式paint.setStyle()和宽度大小paint.setStrokeWidth()的特性来实现。代码很简单,开始的角度选择-90,从头顶开始画。这样实现的是一个顺时针的倒计时效果。如果你想实现酷狗的逆时针效果,就控制mSweepAngle的值用mSweepAngle = 360 - mSweepAngle开始就可以了。
@Override
protected void onDraw(Canvas canvas) {
int padding = dp2px(4);
mRect.top = padding;
mRect.left = padding;
mRect.right = getWidth() - padding;
mRect.bottom = getHeight() - padding;
// 画倒计时线内圆
canvas.drawArc(mRect, //弧线所使用的矩形区域大小
-90, //开始角度
mSweepAngle, //扫过的角度
false, //是否使用中心
mBackgroundPaint); // 设置画笔
super.onDraw(canvas);
}
什么是插值动画?
为了让动画过度的更加自然或者添加一些动画效果,比如匀速运动、加速运动、减速运动、弹跳运动等等,这些的动画的效果就是靠插值来实现的。在Android中系统内置了一些插值,更加直观的展示下面介绍的动画效果。
插值 | 说明 |
---|---|
LinearInterpolator | 以常量速率改变 |
BounceInterpolator | 动画结束的时候弹起 |
CycleInterpolator | 动画循环播放特定的次数,速率改变沿着正弦曲线 |
DecelerateInterpolator | 在动画开始的地方快然后慢 |
OvershootInterpolator | 向前甩一定值后再回到原来位置 |
AccelerateInterpolator | 在动画开始的地方速率改变比较慢,然后开始加速 |
AnticipateInterpolator | 开始的时候向后然后向前甩 |
AccelerateDecelerateInterpolator | 在动画开始与介绍的地方速率改变比较慢,在中间的时候加速 |
AnticipateOvershootInterpolator | 开始的时候向后然后向前甩一定值后返回最后的值 |
项目使用
这里要定义文本的宽高,因为没有画底部的黑色圆背景,还要设置一下背景图。
<com.example.viewdemo.CountDownTextView
android:id="@+id/tv_skip"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="@drawable/bg_count_down"
android:text="跳过"
android:textColor="#ffffff"
android:textSize="12sp"
android:visibility="visible" />
背景图
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="oval">
<solid android:color="#302d2d2d" />
</shape>
</item>
<item>
<shape android:shape="oval">
<solid android:color="#7F2d2d2d" />
</shape>
</item>
</selector>
完整代码
/**
* 倒计时文本
*/
@SuppressLint("AppCompatCustomView")
public class CountDownTextView extends TextView {
// 倒计时动画时间
private int duration = 5000;
// 动画扫过的角度
private int mSweepAngle = 360;
// 属性动画
private ValueAnimator animator;
// 矩形用来保存位置大小信息
private final RectF mRect = new RectF();
// 圆弧的画笔
private Paint mBackgroundPaint;
public CountDownTextView(Context context) {
this(context, null);
}
public CountDownTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CountDownTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
protected void onDraw(Canvas canvas) {
int padding = 5;
mRect.top = padding;
mRect.left = padding;
mRect.right = getWidth() - padding;
mRect.bottom = getHeight() - padding;
// 画倒计时线内圆
canvas.drawArc(mRect, //弧线所使用的矩形区域大小
-90, //开始角度
mSweepAngle, //扫过的角度
false, //是否使用中心
mBackgroundPaint); // 设置画笔
start();
super.onDraw(canvas);
}
private void init() {
// 设置画笔平滑
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 设置画笔颜色
mBackgroundPaint.setColor(Color.WHITE);
// 设置画笔边框宽度
mBackgroundPaint.setStrokeWidth(5);
// 设置画笔样式为边框类型
mBackgroundPaint.setStyle(Paint.Style.STROKE);
}
/**
* 开始倒计时
*/
public void start() {
// 在动画中
if (mSweepAngle != 360) return;
// 初始化属性动画
animator = ValueAnimator.ofInt(mSweepAngle).setDuration(duration);
// 设置插值
animator.setInterpolator(new LinearInterpolator());
// 设置动画监听
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 获取属性动画返回的动画值
mSweepAngle = (int) animation.getAnimatedValue();
// 重绘自己
invalidate();
}
});
// 开始动画
animator.start();
}
}
来源:https://mp.weixin.qq.com/s/loX-7W6Uzmp8Hlh7bxRfwQ


猜你喜欢
- SpringAOP 通过JoinPoint获取参数名和值在Java8之前,代码编译为class文件后,方法参数的类型固定,但是方法名称会丢失
- 学完了计算机网络课程以后,确实学到了一些网络的概念,初步拥有了对网络的一些认识。这些概念虽然可以用来解释平时网络上遇到的一些问题,但是真正把
- 一、 通过JDK网络类Java.net.HttpURLConnection1.java.net包下的原生java api提供的http请求使
- 今天给大家讲讲 SpringBoot 框架 整合 Elasticsearch 实现海量级数据搜索。一、简介在上篇ElasticSe
- MybatisPlus特性•无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑•损耗小:启动即会自动注入基本 CURD,性能
- 一、ConcurrentBag类ConcurrentBag<T>对外提供的方法没有List<T>那么多,但是同样有E
- 问题现象前段时间升级 Android Studio 3.1.3+ 版本后,决定尝试使用 Kotlin 做 APP 开发看看。结果却发现,修改
- 前言《摩尔庄园》前段时间上线, 持续超出市场预期,相信也有不错的收益。游戏好玩,所有玩家看到了前端,但是做一款游戏,离不开后台游戏服务器的支
- 前言Java8 的新特性:Lambda表达式、强大的 Stream API、全新时间日期 API、ConcurrentHashMap、Met
- 在此附上超详细JDK1.8安装与配置超详细JDK1.8安装与配置一、卸载JDK应用程序①在开始处,点击设置②点击应用③点击程序和功能④打开程
- 资源加载器使用Java,您可以使用当前线程的classLoader并尝试加载文件,但是Spring Framework为您提供了更为优雅的解
- 1. 添加maven依赖包<dependency> <groupId>org.apache.calcit
- 本文实例讲述了Spring实战之Bean的作用域singleton和prototype用法。分享给大家供大家参考,具体如下:一 配置<
- 步骤:1、遍历D盘Source文件夹找出所有名称包含LTE的文件,文件路径存放到List<string>中2、遍历List<
- 在 Intellij Idea 中,我们需要设置 Settings 中的 Java Compiler 和 Project Structure
- SpringBoot集成Mybatis时mybatis.mapper-locations和@MapperScan的作用1、mybatis.m
- 本文实例为大家分享了Android实现倒计时效果的具体代码,供大家参考,具体内容如下一个倒计时的效果先看效果图:直接上代码:这里是关于倒计时
- mybatis 传入null值解决前端传入两个值,如果其中一个为null时,很多时候我们都很困惑,明明传入的是null,为啥mybatis
- 在使用C#进行相关编程的时候,有时候我们需要获取系统相关的进程信息。那么在C#中如何获取系统的所有进程那?下面请跟小编一起来操作。1、首先新
- 原因是新建类的模板被更改了,匹配符变成了大写,并且没有默认修饰符。不想自己改的,粘上去就好了,不过我只加了默认的。#if (${PACKAG