欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现启动页倒计时效果

程序员文章站 2022-06-27 10:05:40
今天介绍一个很简单的倒计时动画,仿酷狗音乐的启动页倒计时效果,也是大多数app在用的一个动画,来看看效果图:整体的思路就是用一个平滑的帧动画来画圆弧就行了。这篇文章学到什么?了解属性动画valuean...

今天介绍一个很简单的倒计时动画,仿酷狗音乐的启动页倒计时效果,也是大多数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();
    }
}

以上就是android实现启动页倒计时效果的详细内容,更多关于android 启动页倒计时的资料请关注其它相关文章!