<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仿360市場下載按鈕

          共 9390字,需瀏覽 19分鐘

           ·

          2022-02-15 12:21

          先看一下效果:



          無論多復(fù)雜的動(dòng)畫我們都是可以分割成小單元的,然后分步來實(shí)現(xiàn)。這個(gè)動(dòng)畫大概分為收縮,準(zhǔn)備,加載,完成幾個(gè)部分。為此定義一個(gè)枚舉類來描述view的狀態(tài)。

          public enum Status { NORMAL, START, PRE, EXPAND, LOAD, END }


          收縮動(dòng)畫

          使用動(dòng)畫不斷改變圓角矩形的寬度,觸發(fā)重繪。代碼如下:

          private void initAnim() {        Animation animation1 = new Animation() {            @Override            protected void applyTransformation(float interpolatedTime, Transformation t) {                mCurrLength = mWidth * (1 - interpolatedTime);                if (mCurrLength < mHeight) {                    mCurrLength = mHeight;                    clearAnimation();                    mAngleAnim.start();                }                invalidate();            }        };
          animation1.setDuration(mShrinkDuration); animation1.setInterpolator(new LinearInterpolator()); animation1.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { mStatus = Status.START; }
          @Override public void onAnimationEnd(Animation animation) {
          }
          @Override public void onAnimationRepeat(Animation animation) {
          } }); mShrinkAnim = animation1; ...}


          onDraw中繪制:

                  if (mStatus == Status.START || mStatus == Status.NORMAL) {            float left = (mWidth - mCurrLength) / 2f;            float right = (mWidth + mCurrLength) / 2f;            float r = mHeight / 2f;            canvas.drawRoundRect(new RectF(left, 0, right, mHeight), r, r, mBgPaint);            if (mStatus == Status.NORMAL) {                Paint.FontMetrics fm = mTextPaint.getFontMetrics();                float y = mHeight / 2 + (fm.descent - fm.ascent) / 2 - fm.descent;                canvas.drawText("下載", mWidth / 2, y, mTextPaint);            }        }


          準(zhǔn)備動(dòng)畫


          此時(shí)旋轉(zhuǎn)動(dòng)畫,是通過canvas繪制背景圓和三個(gè)小圓,然后不斷旋轉(zhuǎn)畫布來實(shí)現(xiàn)的,具體求圓心坐標(biāo)和角度動(dòng)畫我們直接看代碼:

           ValueAnimator animator = ValueAnimator.ofFloat(0, 1);        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mAngle += mPreAnimSpeed;                invalidate();            }        });        animator.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {                mStatus = Status.PRE;            }
          @Override public void onAnimationEnd(Animator animation) { mAngleAnim.cancel(); startAnimation(mTranslateAnim); }
          @Override public void onAnimationCancel(Animator animation) {
          }
          @Override public void onAnimationRepeat(Animator animation) {
          } });
          animator.setDuration(mPreAnimDuration); animator.setInterpolator(new LinearInterpolator()); mAngleAnim = animator;


          onDraw中繪制代碼:

            if (mStatus == Status.PRE) {            canvas.drawCircle(mWidth / 2f, mHeight / 2f, mHeight / 2f, mBgPaint);            canvas.save();            mTextPaint.setStyle(Paint.Style.FILL);            canvas.rotate(mAngle, mWidth / 2, mHeight / 2);            //大圓的圓心 半徑            float cX = mWidth / 2f;            float cY = mHeight / 2f;            float radius = mHeight / 2 / 3f;            canvas.drawCircle(cX, cY, radius, mTextPaint);            //上方小圓的參數(shù)            float rr = radius / 2f;            float cYY = mHeight / 2 - (radius + rr / 3);            canvas.drawCircle(cX, cYY, rr, mTextPaint);            //左下小圓參數(shù)            float cXX = (float) (cX - Math.sqrt(2) / 2f * (radius + rr / 3f));            cYY = (float) (mHeight / 2 + Math.sqrt(2) / 2f * (radius + rr / 3f));            canvas.drawCircle(cXX, cYY, rr, mTextPaint);            //右下小圓參數(shù)            cXX = (float) (cX + Math.sqrt(2) / 2f * (radius + rr / 3f));            canvas.drawCircle(cXX, cYY, rr, mTextPaint);            canvas.restore();        }


          展開動(dòng)畫


          展開動(dòng)畫也是不斷改變view的寬度并重繪圓角矩形,同時(shí)需要對(duì)準(zhǔn)備動(dòng)畫的狀態(tài)進(jìn)行向右位移。

           Animation animator1 = new Animation() {            @Override            protected void applyTransformation(float interpolatedTime, Transformation t) {                mCurrLength = mHeight + (mWidth - mHeight) * interpolatedTime;                mTranslationX = (mWidth - mHeight) / 2 * interpolatedTime;                invalidate();            }        };        animator1.setAnimationListener(new Animation.AnimationListener() {            @Override            public void onAnimationStart(Animation animation) {                mStatus = Status.EXPAND;            }
          @Override public void onAnimationEnd(Animation animation) { clearAnimation(); mLoadAngleAnim.start(); mMovePointAnim.start(); }
          @Override public void onAnimationRepeat(Animation animation) {
          } }); animator1.setDuration(mExpandAnimDuration); animator1.setInterpolator(new LinearInterpolator()); mTranslateAnim = animator1;


          onDraw中繪制代碼

            if (mStatus == Status.EXPAND) {            float left = (mWidth - mCurrLength) / 2f;            float right = (mWidth + mCurrLength) / 2f;            float r = mHeight / 2f;            canvas.drawRoundRect(new RectF(left, 0, right, mHeight), r, r, mBgPaint);            canvas.save();            mTextPaint.setStyle(Paint.Style.FILL);            canvas.translate(mTranslationX, 0);            //大圓的圓心 半徑            float cX = mWidth / 2f;            float cY = mHeight / 2f;            float radius = mHeight / 2 / 3f;            canvas.drawCircle(cX, cY, radius, mTextPaint);            //上方小圓的參數(shù)            float rr = radius / 2f;            float cYY = mHeight / 2 - (radius + rr / 3);            canvas.drawCircle(cX, cYY, rr, mTextPaint);            //左下小圓參數(shù)            float cXX = (float) (cX - Math.sqrt(2) / 2f * (radius + rr / 3f));            cYY = (float) (mHeight / 2 + Math.sqrt(2) / 2f * (radius + rr / 3f));            canvas.drawCircle(cXX, cYY, rr, mTextPaint);            //右下小圓參數(shù)            cXX = (float) (cX + Math.sqrt(2) / 2f * (radius + rr / 3f));            canvas.drawCircle(cXX, cYY, rr, mTextPaint);            canvas.restore();        }


          加載動(dòng)畫


          加載動(dòng)畫分三部分,右側(cè)的旋轉(zhuǎn)動(dòng)畫,正弦軌跡運(yùn)動(dòng)的小球動(dòng)畫,進(jìn)度更新的動(dòng)畫。正弦動(dòng)畫要求出正弦函數(shù)的周期,y軸偏移量,x軸偏移量。

           ValueAnimator animator2 = ValueAnimator.ofFloat(0, 1);        animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mLoadAngle += mLoadRotateAnimSpeed;                invalidate();            }        });        animator2.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {                mStatus = Status.LOAD;            }
          @Override public void onAnimationEnd(Animator animation) { mLoadAngleAnim.cancel(); }
          @Override public void onAnimationCancel(Animator animation) {
          }
          @Override public void onAnimationRepeat(Animator animation) {
          } }); animator2.setDuration(Integer.MAX_VALUE); animator2.setInterpolator(new LinearInterpolator()); mLoadAngleAnim = animator2;


          onDraw中繪制代碼:

           if (mStatus == Status.LOAD || mStatus == Status.END) {            float left = (mWidth - mCurrLength) / 2f;            float right = (mWidth + mCurrLength) / 2f;            float r = mHeight / 2f;            mBgPaint.setColor(mProgressColor);            canvas.drawRoundRect(new RectF(left, 0, right, mHeight), r, r, mBgPaint);            if (mProgress != 100) {                for (int i = 0; i < mFourMovePoints.length; i++) {                    if (mFourMovePoints[i].isDraw)                        canvas.drawCircle(mFourMovePoints[i].moveX, mFourMovePoints[i].moveY, mFourMovePoints[i].radius, mTextPaint);                }            }            float progressRight = mProgress * mWidth / 100f;            mBgPaint.setColor(mBgColor);            canvas.save();            canvas.clipRect(0, 0, progressRight, mHeight);            canvas.drawRoundRect(new RectF(left, 0, right, mHeight), r, r, mBgPaint);            canvas.restore();
          if (mProgress != 100) { canvas.drawCircle(mWidth - mHeight / 2, mHeight / 2, mHeight / 2, mBgPaint); canvas.save(); mTextPaint.setStyle(Paint.Style.FILL); canvas.rotate(mLoadAngle, mWidth - mHeight / 2, mHeight / 2); canvas.drawCircle(mWidth - mHeight + 30, getCenterY(mWidth - mHeight + 30, 5), 5, mTextPaint); canvas.drawCircle(mWidth - mHeight + 45, getCenterY(mWidth - mHeight + 45, 8), 8, mTextPaint); canvas.drawCircle(mWidth - mHeight + 68, getCenterY(mWidth - mHeight + 68, 11), 11, mTextPaint); canvas.drawCircle(mWidth - mHeight + 98, getCenterY(mWidth - mHeight + 98, 14), 14, mTextPaint); canvas.restore(); }
          Paint.FontMetrics fm = mTextPaint.getFontMetrics(); float y = mHeight / 2 + (fm.descent - fm.ascent) / 2 - fm.descent; canvas.drawText(mProgress + "%", mWidth / 2, y, mTextPaint); }


          源碼地址:

          https://github.com/ietf626/360DownLoadView


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

          瀏覽 48
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  老熟妇乱伦视频 | 99热免费在线观看 | 国产黄色视频在线观看 | 小黄片视频在线播放 | 天天日天天摸天天爽 |