android Animation 動畫繪製邏輯

 

參考:http://www.jianshu.com/p/3683a69c38ea

 

 
 
一、View.draw(Canvas) 其中步驟爲:
/*
* Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
* 1. Draw the background
* 2. If necessary, save the canvas' layers to prepare for fading
* 3. Draw view's content
* 4. Draw children
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
*/
二、ViewGroup.dispatchDraw(Canvas);若是控件爲ViewGroup或者其子類,須要繪製子類 

三、ViewGroup.drawChild(Canvas canvas, View child, long drawingtime)

四、View.draw(Canvas canvas, ViewGroup parent, long drawingTime); 這個方法裏面實現動畫
  // 以下代碼段獲取Animation的矩陣、alipa等值
  if (a != null) {
   more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
   concatMatrix = a.willChangeTransformationMatrix();
   if (concatMatrix) {
   mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
   }
   transformToApply = parent.getChildTransformation();
  }

// 主要方法爲 applyLegacyAnimation,其代碼段
  final Transformation t = parent.getChildTransformation(); // 取出父控件保存的Transformation 對象
  boolean more = a.getTransformation(drawingTime, t, 1f); // 用animation中的矩陣變化值填充 對象t; 其中a爲程序員設置的動畫對象
  
  // Animation 的 getTransformation代碼段
  final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
  applyTransformation(interpolatedTime, outTransformation); // 具體填充傳入參數Transformation的方法,它是一個空方法,具體實現由子類負責

  //例如:RotateAnimation 的 applyTransformation 方法,其中代碼段:
  float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
  float scale = getScaleFactor();

  if (mPivotX == 0.0f && mPivotY == 0.0f) {
   t.getMatrix().setRotate(degrees);
  } else {
   t.getMatrix().setRotate(degrees, mPivotX * scale, mPivotY * scale); // 將旋轉角度設置到transformation的矩陣中,其餘子類也是類似邏輯
  }
   // View.draw( , , )真正實現動畫的代碼段:
  canvas.translate(-transX, -transY);
  canvas.concat(transformToApply.getMatrix()); // 將從動畫中取出的矩陣,傳遞給canvas實現動畫效果
  canvas.translate(transX, transY);

  // View.draw(, ,)關鍵代碼段:
  // Fast path for layouts with no backgrounds
  if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
   mPrivateFlags &= ~PFLAG_DIRTY_MASK;
   dispatchDraw(canvas); //
  } else {
   draw(canvas);// 執行動畫變換以後,接着繪製視圖
  }

 

結論:一、Animation 動畫中起關鍵做用的類是Transformation, animation負責計算動畫的矩陣變換,Transformation負責將變換傳遞給Canvas.二、Animation 動畫只是對Canvas作了矩陣變換,並無修改其屬性值,這是它和屬性動畫的最大區別。三、Alpha值的修改也在draw方法中保存了圖層,不影響屬性值
相關文章
相關標籤/搜索