<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Tween Animation ## 補間動畫的使用 ``` Animation translateAnimation = new TranslateAnimation(0, 100, 0, 0); translateAnimation.setDuration(500); translateAnimation.setInterpolator(new AccelerateInterpolator()); translateAnimation.setFillAfter(true);//設置動畫結束后保持當前的位置(即不返回到動畫開始前的位置) imageView.startAnimation(translateAnimation); ``` ## TweenAnimation流程圖 ![](../images/TweenAnimation流程圖.png) ## 補間動畫代碼的執行過程 ### start View: ``` public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { //部分代碼省略 public void startAnimation(Animation animation) { animation.setStartTime(Animation.START_ON_FIRST_FRAME); setAnimation(animation); invalidateParentCaches(); invalidate(true); } void invalidate(boolean invalidateCache) { invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true); } void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache, boolean fullInvalidate) { if (mGhostView != null) { mGhostView.invalidate(true); return; } if (skipInvalidate()) { return; } if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED || (fullInvalidate && isOpaque() != mLastIsOpaque)) { //部分代碼省略 // Propagate the damage rectangle to the parent view. final AttachInfo ai = mAttachInfo; final ViewParent p = mParent; if (p != null && ai != null && l < r && t < b) { final Rect damage = ai.mTmpInvalRect; damage.set(l, t, r, b); //執行ViewParent的invalidateChild方法 p.invalidateChild(this, damage); } //部分代碼省略 } } } ``` ViewGroup ``` public abstract class ViewGroup extends View implements ViewParent, ViewManager { /***部分代碼省略***/ public final void invalidateChild(View child, final Rect dirty) { ViewParent parent = this; final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { /***部分代碼省略***/ do { /***部分代碼省略***/ //向頂部的View便利找到根View,即:ViewRootImpl //執行ViewRootImpl的invalidateChildInParent方法 parent = parent.invalidateChildInParent(location, dirty); if (view != null) { // Account for transform on current parent Matrix m = view.getMatrix(); if (!m.isIdentity()) { RectF boundingRect = attachInfo.mTmpTransformRect; boundingRect.set(dirty); m.mapRect(boundingRect); dirty.set((int) (boundingRect.left - 0.5f), (int) (boundingRect.top - 0.5f), (int) (boundingRect.right + 0.5f), (int) (boundingRect.bottom + 0.5f)); } } /***部分代碼省略***/ } while (parent != null); } } } ``` ViewRootImpl ``` public final class ViewRootImpl implements ViewParent, View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks { /***部分代碼省略***/ @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { checkThread(); /***部分代碼省略***/ invalidateRectOnScreen(dirty); return null; } private void invalidateRectOnScreen(Rect dirty) { /***部分代碼省略***/ if (!mWillDrawSoon && (intersected || mIsAnimating)) { //開始View的繪制任務 scheduleTraversals(); } } } ``` 之前寫過一篇文章 [ViewRootImpl的獨白,我不是一個View(布局篇)](http://dandanlove.com/2017/12/11/viewrootimpl-activity/) 其中 [ViewRootImpl對mView進行操作](http://dandanlove.com/2017/12/11/viewrootimpl-activity/#ViewRootImpl%E5%AF%B9mView%E8%BF%9B%E8%A1%8C%E6%93%8D%E4%BD%9C) 講述了再`ViewRootImpl` 中View的繪制。 ### draw ``` public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { //部分代碼省略 public void draw(Canvas canvas) { /***部分代碼省略***/ //如果有子 View(DecorView當然有子View),就會調用dispatchDraw() 將繪制事件通知給子 View。 //ViewGroup 重寫了 dispatchDraw(),調用了 drawChild() //drawChild() 調用了子 View 的 draw(Canvas, ViewGroup, long) } boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) { final boolean hardwareAcceleratedCanvas = canvas.isHardwareAccelerated(); /***部分代碼省略***/ Transformation transformToApply = null; boolean concatMatrix = false; final boolean scalingRequired = mAttachInfo != null && mAttachInfo.mScalingRequired; final Animation a = getAnimation(); if (a != null) { more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired); concatMatrix = a.willChangeTransformationMatrix(); if (concatMatrix) { mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM; } transformToApply = parent.getChildTransformation(); } else { /***部分代碼省略***/ } /***部分代碼省略***/ } private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime, Animation a, boolean scalingRequired) { /***部分代碼省略***/ //繪制動畫的當前幀,并獲取當前動畫的狀態(是否繼續運行) boolean more = a.getTransformation(drawingTime, t, 1f); if (scalingRequired && mAttachInfo.mApplicationScale != 1f) { if (parent.mInvalidationTransformation == null) { parent.mInvalidationTransformation = new Transformation(); } invalidationTransform = parent.mInvalidationTransformation; a.getTransformation(drawingTime, invalidationTransform, 1f); } else { invalidationTransform = t; } //如果動畫沒有結果 if (more) { if (!a.willChangeBounds()) { if ((flags & (ViewGroup.FLAG_OPTIMIZE_INVALIDATE | ViewGroup.FLAG_ANIMATION_DONE)) == ViewGroup.FLAG_OPTIMIZE_INVALIDATE) { parent.mGroupFlags |= ViewGroup.FLAG_INVALIDATE_REQUIRED; } else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) { // The child need to draw an animation, potentially offscreen, so // make sure we do not cancel invalidate requests parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION; //進行繪制 parent.invalidate(mLeft, mTop, mRight, mBottom); } } else { /***部分代碼省略***/ //進行繪制 parent.invalidate(left, top, left + (int) (region.width() + .5f), top + (int) (region.height() + .5f)); } } return more; } } ``` ### running ``` public abstract class Animation implements Cloneable { /***部分代碼省略***/ public boolean getTransformation(long currentTime, Transformation outTransformation) { /***部分代碼省略***/ //執行時間是否過期 final boolean expired = normalizedTime >= 1.0f; mMore = !expired; //動畫進度為0.0~1.0之間 if (!mFillEnabled) normalizedTime = Math.max(Math.min(normalizedTime, 1.0f), 0.0f); if ((normalizedTime >= 0.0f || mFillBefore) && (normalizedTime <= 1.0f || mFillAfter)) { /***部分代碼省略***/ //插值器計算動畫執行進度 final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime); //真正的動畫效果代碼執行處(通過矩陣變化) applyTransformation(interpolatedTime, outTransformation); } //如果動畫繪制完成 if (expired) { //判斷動畫是否需要繼續循環 if (mRepeatCount == mRepeated) { if (!mEnded) { mEnded = true; guard.close(); fireAnimationEnd(); } } else { if (mRepeatCount > 0) { mRepeated++; } if (mRepeatMode == REVERSE) { mCycleFlip = !mCycleFlip; } mStartTime = -1; mMore = true; fireAnimationRepeat(); } } if (!mMore && mOneMoreTime) { mOneMoreTime = false; return true; } return mMore; } } ``` ## 其他 通過代碼分析可以證明補間動畫也不會存在內存泄露的問題,因為他是靠著View的繪制來完成每一幀動效的展示。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看