Android View篇之啓動頁倒計時動畫的實現

Hello,小夥伴們你們好,今天介紹一個很簡單的倒計時動畫,仿酷狗音樂的啓動頁倒計時效果,也是大多數APP在用的一個動畫,來看看效果圖:java

倒計時動畫

實現思路android

看看是否是很簡單,畫個圈圈動起來,總體的思路就是用一個平滑的幀動畫來畫圓弧就好了。git

這篇文章學到什麼?github

  • 瞭解屬性動畫ValueAnimator的用法
  • 瞭解動畫屬性插值Interpolator,讓動畫過分得更天然
  • 如何畫圓弧

開始準備canvas

新建一個類繼承TextView,由於中間還有跳過的文本,因此選擇用TextView來畫個動起來的背景圖。markdown

/** * 倒計時文本 * Created by ChenRui on 2017/10/31 0031 23:01. */
public class CountDownTextView extends RaeTextView {
    // 倒計時動畫時間
    private int duration = 5000;
    // 動畫掃過的角度
    private int mSweepAngle = 360;
    // 屬性動畫
    private ValueAnimator animator;
    // 矩形用來保存位置大小信息
    private final RectF mRect = new RectF();
    // 圓弧的畫筆
    private Paint mBackgroundPaint;

    public CountDownTextView(Context context) {
        super(context);
    }

    public CountDownTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CountDownTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    void init() {
        super.init();
        // 設置畫筆平滑
        mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // 設置畫筆顏色
        mBackgroundPaint.setColor(Color.WHITE);
        // 設置畫筆邊框寬度
        mBackgroundPaint.setStrokeWidth(dp2px(2));
        // 設置畫筆樣式爲邊框類型
        mBackgroundPaint.setStyle(Paint.Style.STROKE);
    }
複製代碼

開始動畫less

原理: 利用圓的360度角來作屬性動畫,讓它平滑的分配作每幀動畫的角度值,而後調用invalidate()來重繪本身自己,從而進入到自己的onDraw()方法來畫圖。ide

/** * 開始倒計時 */
    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();
    }
複製代碼

畫圓弧oop

畫圓弧比較簡單, 從效果圖來看,有的同窗可能剛開始覺得要畫兩個圓,一個背景的內圓和一個白色邊框的大圓,其實這裏能夠利用畫筆設置畫筆樣式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中系統內置了一些插值,這裏作下搬運工記錄一下。推薦一個能在線運行Interpolator的效果以及數學公式定義的網站 inloop.github.io/interpolato… 更加直觀的展現下面介紹的動畫效果。

插值 說明
LinearInterpolator 以常量速率改變
BounceInterpolator 動畫結束的時候彈起
CycleInterpolator 動畫循環播放特定的次數,速率改變沿着正弦曲線
DecelerateInterpolator 在動畫開始的地方快而後慢
OvershootInterpolator 向前甩必定值後再回到原來位置
AccelerateInterpolator 在動畫開始的地方速率改變比較慢,而後開始加速
AnticipateInterpolator 開始的時候向後而後向前甩
AccelerateDecelerateInterpolator 在動畫開始與介紹的地方速率改變比較慢,在中間的時候加速
AnticipateOvershootInterpolator 開始的時候向後而後向前甩必定值後返回最後的值

項目使用

這裏要定義文本的寬高,由於沒有畫底部的黑色圓背景,還要設置一下背景圖。

<com.rae.cnblogs.widget.CountDownTextView android:id="@+id/tv_skip" style="@style/Widget.AppCompat.Button.Borderless" android:layout_width="40dp" android:layout_height="40dp" android:background="@drawable/bg_count_down" android:text="跳過" android:textColor="#ffffff" android:textSize="12sp" />
複製代碼

背景圖

<?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>
複製代碼

到這裏結束啦,但願對你有幫助,本篇文章的源碼都在開源的博客園Android客戶端這裏。 喜歡的給個start~~

相關文章
相關標籤/搜索