<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android仿酷狗音樂的啟動(dòng)頁倒計(jì)時(shí)效果

          共 6405字,需瀏覽 13分鐘

           ·

          2021-04-17 10:59

          今天介紹一個(gè)很簡單的倒計(jì)時(shí)動(dòng)畫,仿酷狗音樂的啟動(dòng)頁倒計(jì)時(shí)效果,也是大多數(shù)APP在用的一個(gè)動(dòng)畫,來看看效果圖:



          整體的思路就是用一個(gè)平滑的幀動(dòng)畫來畫圓弧就行了。


          這篇文章學(xué)到什么?


          • 了解屬性動(dòng)畫ValueAnimator的用法

          • 了解動(dòng)畫屬性插值Interpolator,讓動(dòng)畫過度得更自然

          • 如何畫圓弧

          開始準(zhǔn)備

          新建一個(gè)類繼承TextView,因?yàn)橹虚g還有跳過的文本,所以選擇用TextView來畫個(gè)動(dòng)起來的背景圖。

          /** * 倒計(jì)時(shí)文本 */@SuppressLint("AppCompatCustomView")public class CountDownTextView extends TextView {    // 倒計(jì)時(shí)動(dòng)畫時(shí)間    private int duration = 5000;    // 動(dòng)畫掃過的角度    private int mSweepAngle = 360;    // 屬性動(dòng)畫    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() { // 設(shè)置畫筆平滑 mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 設(shè)置畫筆顏色 mBackgroundPaint.setColor(Color.WHITE); // 設(shè)置畫筆邊框?qū)挾?/span> mBackgroundPaint.setStrokeWidth(5); // 設(shè)置畫筆樣式為邊框類型 mBackgroundPaint.setStyle(Paint.Style.STROKE); }}


          開始動(dòng)畫


          原理:利用圓的360度角來做屬性動(dòng)畫,讓它平滑的分配做每幀動(dòng)畫的角度值,然后調(diào)用invalidate()來重繪自己本身,從而進(jìn)入到本身的onDraw()方法來畫圖。

              /**     * 開始倒計(jì)時(shí)     */    public void start() {        // 在動(dòng)畫中        if (mSweepAngle != 360) return;        //  初始化屬性動(dòng)畫        animator = ValueAnimator.ofInt(mSweepAngle).setDuration(duration);        // 設(shè)置插值        animator.setInterpolator(new LinearInterpolator());        // 設(shè)置動(dòng)畫監(jiān)聽        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                // 獲取屬性動(dòng)畫返回的動(dòng)畫值                mSweepAngle = (int) animation.getAnimatedValue();                // 重繪自己                invalidate();            }        });
          // 開始動(dòng)畫 animator.start(); }


          畫圓弧


          畫圓弧比較簡單, 從效果圖來看,有的同學(xué)可能剛開始以為要畫兩個(gè)圓,一個(gè)背景的內(nèi)圓和一個(gè)白色邊框的大圓,其實(shí)這里可以利用畫筆設(shè)置畫筆樣式paint.setStyle()和寬度大小paint.setStrokeWidth()的特性來實(shí)現(xiàn)。代碼很簡單,開始的角度選擇-90,從頭頂開始畫。這樣實(shí)現(xiàn)的是一個(gè)順時(shí)針的倒計(jì)時(shí)效果。如果你想實(shí)現(xiàn)酷狗的逆時(shí)針效果,就控制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;
          // 畫倒計(jì)時(shí)線內(nèi)圓 canvas.drawArc(mRect, //弧線所使用的矩形區(qū)域大小 -90, //開始角度 mSweepAngle, //掃過的角度 false, //是否使用中心 mBackgroundPaint); // 設(shè)置畫筆
          super.onDraw(canvas);    }


          什么是插值動(dòng)畫?


          為了讓動(dòng)畫過度的更加自然或者添加一些動(dòng)畫效果,比如勻速運(yùn)動(dòng)、加速運(yùn)動(dòng)、減速運(yùn)動(dòng)、彈跳運(yùn)動(dòng)等等,這些的動(dòng)畫的效果就是靠插值來實(shí)現(xiàn)的。在Android中系統(tǒng)內(nèi)置了一些插值,更加直觀的展示下面介紹的動(dòng)畫效果。


          插值說明
          LinearInterpolator以常量速率改變
          BounceInterpolator動(dòng)畫結(jié)束的時(shí)候彈起
          CycleInterpolator動(dòng)畫循環(huán)播放特定的次數(shù),速率改變沿著正弦曲線
          DecelerateInterpolator在動(dòng)畫開始的地方快然后慢
          OvershootInterpolator向前甩一定值后再回到原來位置
          AccelerateInterpolator在動(dòng)畫開始的地方速率改變比較慢,然后開始加速
          AnticipateInterpolator開始的時(shí)候向后然后向前甩
          AccelerateDecelerateInterpolator在動(dòng)畫開始與介紹的地方速率改變比較慢,在中間的時(shí)候加速
          AnticipateOvershootInterpolator開始的時(shí)候向后然后向前甩一定值后返回最后的值


          項(xiàng)目使用


          這里要定義文本的寬高,因?yàn)闆]有畫底部的黑色圓背景,還要設(shè)置一下背景圖。

           <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>


          完整代碼

          /** * 倒計(jì)時(shí)文本 */@SuppressLint("AppCompatCustomView")public class CountDownTextView extends TextView {    // 倒計(jì)時(shí)動(dòng)畫時(shí)間    private int duration = 5000;    // 動(dòng)畫掃過的角度    private int mSweepAngle = 360;    // 屬性動(dòng)畫    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;
          // 畫倒計(jì)時(shí)線內(nèi)圓 canvas.drawArc(mRect, //弧線所使用的矩形區(qū)域大小 -90, //開始角度 mSweepAngle, //掃過的角度 false, //是否使用中心 mBackgroundPaint); // 設(shè)置畫筆
          start();
          super.onDraw(canvas);    }
          private void init() { // 設(shè)置畫筆平滑 mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 設(shè)置畫筆顏色 mBackgroundPaint.setColor(Color.WHITE); // 設(shè)置畫筆邊框?qū)挾?/span> mBackgroundPaint.setStrokeWidth(5); // 設(shè)置畫筆樣式為邊框類型 mBackgroundPaint.setStyle(Paint.Style.STROKE); } /** * 開始倒計(jì)時(shí) */ public void start() { // 在動(dòng)畫中 if (mSweepAngle != 360) return; // 初始化屬性動(dòng)畫 animator = ValueAnimator.ofInt(mSweepAngle).setDuration(duration); // 設(shè)置插值 animator.setInterpolator(new LinearInterpolator()); // 設(shè)置動(dòng)畫監(jiān)聽 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { // 獲取屬性動(dòng)畫返回的動(dòng)畫值 mSweepAngle = (int) animation.getAnimatedValue(); // 重繪自己 invalidate(); } });
          // 開始動(dòng)畫 animator.start(); }}


          到這里就結(jié)束啦.

          瀏覽 58
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  女人19毛片A片久久19软件 | 蜜桃网站视频无码高清 | 又大又黄又高潮 | 丁香花电影高清在线小说阅读 | 欧美熟妇精品黑人巨大一二三区 |