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

首頁 > 系統 > Android > 正文

Android自定義View新年煙花、祝福語橫幅動畫

2019-10-22 18:16:32
字體:
來源:轉載
供稿:網友

新年了,項目中要作個動畫,整體要求實現彩帶亂飛,煙花沖天而起,煙花縮放,小雞換圖,小雞飄移,橫幅裁剪、展開等動畫效果,全局大量使用了屬性動畫來實現。

如下效果圖:

Android,View,新年,煙花,動畫

我在實現過程中,橫幅的裁剪計算,搗騰了比較久的時間,初版采用屬性動畫計算float的一個比率值,來配合每一幀的裁剪繪制,如下代碼:

private static class RollView extends View {  private Bitmap mBitmap;  private Rect mSrc;  private Rect mDst;  private int mRollWidth = 60;  private float mRate;  private boolean mIsStopAnim;   public RollView(Context context) {   super(context);   mSrc = new Rect();   mDst = new Rect();  }  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   super.onMeasure(widthMeasureSpec, heightMeasureSpec);  }   @Override  protected void onDraw(Canvas canvas) {   if (mBitmap == null) return;    drawFromMiddleByFloatCompute(canvas);   }   private void drawFromMiddleByFloatCompute(Canvas canvas) {   /*   以下src 都需要加上mBitmap. 的前綴,, 因從drawable拿到的是原始圖片寬高   而適配時,可能view的寬高比 drawable的寬高還小或大   */   final float rate = mRate;    mSrc.left = 0;   mSrc.top = 0;   mSrc.right = mRollWidth;   mSrc.bottom = mBitmap.getHeight();    mDst.left = (int) ((getWidth() / 2 - mRollWidth) - (getWidth() / 2 - mRollWidth) * rate);   mDst.top = 0;   mDst.right = mDst.left + mRollWidth + 1;//因精度問題,這里強制+1   mDst.bottom = getHeight();   canvas.drawBitmap(mBitmap, mSrc, mDst, null);    //中間   int sw = (int) ((mBitmap.getWidth() - mRollWidth * 2) * rate);   mSrc.left = mBitmap.getWidth() / 2 - sw / 2;   mSrc.top = 0;   mSrc.right = mSrc.left + sw;   mSrc.bottom = mBitmap.getHeight();    int dw = (int) ((getWidth() - mRollWidth * 2) * rate);   mDst.left = getWidth() / 2 - dw / 2;   mDst.top = 0;   mDst.right = mDst.left + dw;   mDst.bottom = getHeight();   canvas.drawBitmap(mBitmap, mSrc, mDst, null);    //右邊   mSrc.left = mBitmap.getWidth() - mRollWidth;   mSrc.top = 0;   mSrc.right = mBitmap.getWidth();   mSrc.bottom = mBitmap.getHeight();    mDst.left = (int) (getWidth() / 2 + (getWidth() / 2 - mRollWidth) * rate);   mDst.top = 0;   mDst.right = mDst.left + mRollWidth;   mDst.bottom = getHeight();    canvas.drawBitmap(mBitmap, mSrc, mDst, null);  }   public void setRes(int resId) {   mBitmap = getBitmapFromLocal(resId);  }   @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)  public void startFloatComputeAnim() {   /*   如果有float獲取比率值,從而計算出相應的坐標值,那么可能由于最終在轉成Rect的坐標時,   float to int ,有精度的損失:1個px 而引起效果的不理想   */   ValueAnimator animator = ValueAnimator.ofFloat(0, 1);   animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {   @Override   public void onAnimationUpdate(ValueAnimator animation) {    if (mIsStopAnim) {    animation.cancel();    return;    }    mRate = (float) animation.getAnimatedValue();    invalidate();    }   });   animator.setDuration(2000);   animator.start();  }   public void stopAnim() {   mIsStopAnim = true;  }  } 

> 因float轉int有一個精度損失的問題,所以在計算中強制加上了1px(代碼中有);
這樣雖然解決了有1px沒有繪制的問題,但是會發生繪制時不夠平滑,而出現抖動的情形(在某些devices上)
所以最好還是不要使用float來計算
> 后來,同事猜想使用一個固定int值 來參與計算,可能可以解決上述問題:
比如每秒30幀,這里動畫時長2秒,即共30*2=60幀;
圖片寬度、左畫軸、右畫軸  對  60幀數 做相應的除法及其他計算,可得出一個單幀中 它們應該運動的x距離
> 之后,我又想了一種,使用一個屬性動畫,來計算出從0到getWidth()之間的 動畫值,
從而通過計算,使得橫幅從左向右拉開, 如下:

Android,View,新年,煙花,動畫

代碼就不整體開源了

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 桓台县| 宁南县| 海伦市| 临高县| 塔城市| 元朗区| 柯坪县| 芷江| 辉南县| 封开县| 策勒县| 游戏| 临汾市| 子洲县| 彰武县| 仙桃市| 突泉县| 闵行区| 奉新县| 天镇县| 平陆县| 绵竹市| 阿拉善右旗| 邵东县| 湾仔区| 突泉县| 漳浦县| 柳州市| 蓝山县| 奉贤区| 太原市| 兴和县| 库伦旗| 柞水县| 南部县| 南召县| 岑巩县| 鹰潭市| 留坝县| 花莲县| 五常市|