Android实现启动页倒计时效果

作者:龙旋 时间:2021-07-26 20:50:14 

目录
  • 开始准备

  • 开始动画

  • 画圆弧

  • 项目使用

  • 背景图

  • 完整代码

今天介绍一个很简单的倒计时动画,仿酷狗音乐的启动页倒计时效果,也是大多数APP在用的一个动画,来看看效果图:

Android实现启动页倒计时效果

整体的思路就是用一个平滑的帧动画来画圆弧就行了。

这篇文章学到什么?

了解属性动画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

标签:Android,启动页,倒计时
0
投稿

猜你喜欢

  • 解析C#中委托的同步调用与异步调用(实例详解)

    2022-12-24 19:06:47
  • C#实现套接字发送接收数据

    2023-01-09 19:34:38
  • Vue3源码解读effectScope API及实现原理

    2023-12-11 19:28:49
  • C#中加载dll并调用其函数的实现方法

    2022-06-27 17:14:08
  • c# 类成员初始化顺序的特殊情况

    2021-07-04 18:04:45
  • C# CheckedListBox控件的用法总结

    2023-09-17 13:23:34
  • Android编程使用AlarmManager设置闹钟的方法

    2023-12-11 18:37:42
  • C#中重载相等(==)运算符示例

    2023-01-11 15:10:36
  • 基于C#实现语音识别功能详解

    2023-07-12 18:55:24
  • Idea防沉迷插件StopCoding的安装使用教程

    2023-11-23 07:29:32
  • Android切面编程知识点详解

    2023-05-05 04:18:04
  • Java文件操作之按行读取文件和遍历目录的方法

    2023-11-24 16:58:21
  • C#如何使用Bogus创建模拟数据示例代码

    2023-10-11 10:57:50
  • 深入剖析Java工厂模式让你的代码更灵活

    2022-05-26 00:42:28
  • Java编程实现月食简单代码分享

    2022-12-27 12:33:24
  • 微信小程序支付C#后端源码

    2023-11-21 15:06:29
  • Android RecyclerView添加上拉加载更多功能

    2022-08-02 00:03:51
  • 实现 Java 本地缓存的方法解析

    2023-12-04 01:24:33
  • Android动态添加碎片代码实例

    2023-10-19 23:35:13
  • 详解Java中String类的各种用法

    2022-03-10 12:48:35
  • asp之家 软件编程 m.aspxhome.com