欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2018年01月24日 09:13:38   作者:匆忙擁擠repeat  
這篇文章主要為大家詳細(xì)介紹了Android自定義View新年煙花、祝福語橫幅動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

如下效果圖:

我在實現(xiàn)過程中,橫幅的裁剪計算,搗騰了比較久的時間,初版采用屬性動畫計算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獲取比率值,從而計算出相應(yīng)的坐標(biāo)值,那么可能由于最終在轉(zhuǎn)成Rect的坐標(biāo)時, 
  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轉(zhuǎn)int有一個精度損失的問題,所以在計算中強制加上了1px(代碼中有);
這樣雖然解決了有1px沒有繪制的問題,但是會發(fā)生繪制時不夠平滑,而出現(xiàn)抖動的情形(在某些devices上)
所以最好還是不要使用float來計算
> 后來,同事猜想使用一個固定int值 來參與計算,可能可以解決上述問題:
比如每秒30幀,這里動畫時長2秒,即共30*2=60幀;
圖片寬度、左畫軸、右畫軸  對  60幀數(shù) 做相應(yīng)的除法及其他計算,可得出一個單幀中 它們應(yīng)該運動的x距離
> 之后,我又想了一種,使用一個屬性動畫,來計算出從0到getWidth()之間的 動畫值,
從而通過計算,使得橫幅從左向右拉開, 如下:

代碼就不整體開源了

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論