国产探花免费观看_亚洲丰满少妇自慰呻吟_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開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 礼泉县| 饶平县| 天峨县| 天门市| 五莲县| 富裕县| 萨迦县| 丁青县| 广汉市| 高邑县| 昂仁县| 南阳市| 收藏| 德州市| 浦东新区| 天全县| 宝鸡市| 光山县| 涿鹿县| 隆安县| 罗山县| 壶关县| 咸阳市| 钟祥市| 平罗县| 宜阳县| 宽甸| 东平县| 嘉祥县| 康马县| 堆龙德庆县| 万荣县| 根河市| 荆门市| 宁国市| 大安市| 庆城县| 瑞金市| 资阳市| 遵义市| 麦盖提县|