国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿360市場下載按鈕的實現方法

2019-10-23 18:28:49
字體:
來源:轉載
供稿:網友

首先來看看效果圖:

android,按鈕樣式,開關按鈕,圓角按鈕

無論多復雜的動畫我們都是可以分割成小單元的,然后分步來實現。這個動畫大概分為收縮,準備,加載,完成幾個部分。為此定義一個枚舉類來描述view的狀態。

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

收縮動畫

使用動畫不斷改變圓角矩形的寬度,觸發重繪。代碼如下:

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); } }

準備動畫

此時旋轉動畫,是通過canvas繪制背景圓和三個小圓,然后不斷旋轉畫布來實現的,具體求圓心坐標和角度動畫我們直接看代碼:

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); //上方小圓的參數 float rr = radius / 2f; float cYY = mHeight / 2 - (radius + rr / 3); canvas.drawCircle(cX, cYY, rr, mTextPaint); //左下小圓參數 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); //右下小圓參數 cXX = (float) (cX + Math.sqrt(2) / 2f * (radius + rr / 3f)); canvas.drawCircle(cXX, cYY, rr, mTextPaint); canvas.restore(); }

展開動畫

展開動畫也是不斷改變view的寬度并重繪圓角矩形,同時需要對準備動畫的狀態進行向右位移。

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); //上方小圓的參數 float rr = radius / 2f; float cYY = mHeight / 2 - (radius + rr / 3); canvas.drawCircle(cX, cYY, rr, mTextPaint); //左下小圓參數 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); //右下小圓參數 cXX = (float) (cX + Math.sqrt(2) / 2f * (radius + rr / 3f)); canvas.drawCircle(cXX, cYY, rr, mTextPaint); canvas.restore(); }

加載動畫

加載動畫分三部分,右側的旋轉動畫,正弦軌跡運動的小球動畫,進度更新的動畫。正弦動畫要求出正弦函數的周期,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); }

項目主頁:http://www.open-open.com/lib/view/home/1494985743108

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黄平县| 孟村| 古田县| 婺源县| 金塔县| 罗田县| 万载县| 大理市| 清水河县| 桐城市| 麻城市| 大新县| 商河县| 西乌珠穆沁旗| 秦皇岛市| 永清县| 黎城县| 大港区| 沙湾县| 涟源市| 辽阳市| 阳江市| 金秀| 东平县| 正安县| 武夷山市| 台湾省| 大宁县| 金湖县| 兴城市| 子长县| 深水埗区| 庄河市| 怀来县| 乡城县| 大港区| 宽城| 聂拉木县| 游戏| 奉新县| 泰州市|