mobile/android/base/animation/AnimatorProxy.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko.animation;
     8 import android.graphics.Matrix;
     9 import android.graphics.RectF;
    10 import android.os.Build;
    11 import android.view.View;
    12 import android.view.ViewGroup;
    13 import android.view.animation.Animation;
    14 import android.view.animation.AnimationUtils;
    15 import android.view.animation.Transformation;
    17 import java.lang.ref.WeakReference;
    18 import java.util.WeakHashMap;
    20 class AnimatorProxy {
    21     private static final WeakHashMap<View, AnimatorProxy> PROXIES =
    22             new WeakHashMap<View, AnimatorProxy>();
    24     private static interface AnimatorProxyImpl {
    25         public float getAlpha();
    26         public void setAlpha(float alpha);
    28         public float getTranslationX();
    29         public void setTranslationX(float translationX);
    31         public float getTranslationY();
    32         public void setTranslationY(float translationY);
    34         public View getView();
    35     }
    37     private AnimatorProxyImpl mImpl;
    39     private AnimatorProxy(AnimatorProxyImpl impl) {
    40         mImpl = impl;
    41     }
    43     public static AnimatorProxy create(View view) {
    44         AnimatorProxy proxy = PROXIES.get(view);
    45         boolean needsAnimationProxy = (Build.VERSION.SDK_INT < 11);
    47         // If the view's animation proxy has been overridden from somewhere else, we need to
    48         // create a new AnimatorProxy for the view.
    49         if (proxy == null || (needsAnimationProxy && proxy.mImpl != view.getAnimation())) {
    50             AnimatorProxyImpl impl = (needsAnimationProxy ? new AnimatorProxyPreHC(view) :
    51                                                             new AnimatorProxyPostHC(view));
    53             proxy = new AnimatorProxy(impl);
    54             PROXIES.put(view, proxy);
    55         }
    57         return proxy;
    58     }
    60     public int getWidth() {
    61         View view = mImpl.getView();
    62         if (view != null)
    63             return view.getWidth();
    65         return 0;
    66     }
    68     public void setWidth(int width) {
    69         View view = mImpl.getView();
    70         if (view != null) {
    71             ViewGroup.LayoutParams lp = view.getLayoutParams();
    72             lp.width = width;
    73             view.setLayoutParams(lp);
    74         }
    75     }
    77     public int getHeight() {
    78         View view = mImpl.getView();
    79         if (view != null)
    80             return view.getHeight();
    82         return 0;
    83     }
    85     public void setHeight(int height) {
    86         View view = mImpl.getView();
    87         if (view != null) {
    88             ViewGroup.LayoutParams lp = view.getLayoutParams();
    89             lp.height = height;
    90             view.setLayoutParams(lp);
    91         }
    92     }
    94     public int getScrollX() {
    95         View view = mImpl.getView();
    96         if (view != null)
    97             return view.getScrollX();
    99         return 0;
   100     }
   102     public int getScrollY() {
   103         View view = mImpl.getView();
   104         if (view != null)
   105             return view.getScrollY();
   107         return 0;
   108     }
   110     public void scrollTo(int scrollX, int scrollY) {
   111         View view = mImpl.getView();
   112         if (view != null)
   113             view.scrollTo(scrollX, scrollY);
   114     }
   116     public float getAlpha() {
   117         return mImpl.getAlpha();
   118     }
   120     public void setAlpha(float alpha) {
   121         mImpl.setAlpha(alpha);
   122     }
   124     public float getTranslationX() {
   125         return mImpl.getTranslationX();
   126     }
   128     public void setTranslationX(float translationX) {
   129         mImpl.setTranslationX(translationX);
   130     }
   132     public float getTranslationY() {
   133         return mImpl.getTranslationY();
   134     }
   136     public void setTranslationY(float translationY) {
   137         mImpl.setTranslationY(translationY);
   138     }
   140     /*
   141      * AnimatorProxyPreHC uses the technique used by the NineOldAndroids described here:
   142      * http://jakewharton.com/advanced-pre-honeycomb-animation/
   143      *
   144      * Some of this code is based on Jake Wharton's AnimatorProxy released as part of
   145      * the NineOldAndroids library under the Apache License 2.0.
   146      */
   147     private static class AnimatorProxyPreHC extends Animation implements AnimatorProxyImpl {
   148         private WeakReference<View> mViewRef;
   150         private final RectF mBefore;
   151         private final RectF mAfter;
   152         private final Matrix mTempMatrix;
   154         private float mAlpha;
   155         private float mTranslationX;
   156         private float mTranslationY;
   158         public AnimatorProxyPreHC(View view) {
   159             mBefore = new RectF();
   160             mAfter = new RectF();
   161             mTempMatrix = new Matrix();
   163             mAlpha = 1;
   164             mTranslationX = 0;
   165             mTranslationY = 0;
   167             loadCurrentTransformation(view);
   169             setDuration(0);
   170             setFillAfter(true);
   171             view.setAnimation(this);
   173             mViewRef = new WeakReference<View>(view);
   174         }
   176         private void loadCurrentTransformation(View view) {
   177             Animation animation = view.getAnimation();
   178             if (animation == null)
   179                 return;
   181             Transformation transformation = new Transformation();
   182             float[] matrix = new float[9];
   184             animation.getTransformation(AnimationUtils.currentAnimationTimeMillis(), transformation);
   185             transformation.getMatrix().getValues(matrix);
   187             mAlpha = transformation.getAlpha();
   188             mTranslationX = matrix[Matrix.MTRANS_X];
   189             mTranslationY = matrix[Matrix.MTRANS_Y];
   190         }
   192         private void prepareForUpdate() {
   193             View view = mViewRef.get();
   194             if (view != null)
   195                 computeRect(mBefore, view);
   196         }
   198         private void computeRect(final RectF r, View view) {
   199             final float w = view.getWidth();
   200             final float h = view.getHeight();
   202             r.set(0, 0, w, h);
   204             final Matrix m = mTempMatrix;
   205             m.reset();
   206             transformMatrix(m, view);
   207             mTempMatrix.mapRect(r);
   209             r.offset(view.getLeft(), view.getTop());
   210         }
   212         private void transformMatrix(Matrix m, View view) {
   213             m.postTranslate(mTranslationX, mTranslationY);
   214         }
   216         private void invalidateAfterUpdate() {
   217             View view = mViewRef.get();
   218             if (view == null || view.getParent() == null)
   219                 return;
   221             final RectF after = mAfter;
   222             computeRect(after, view);
   223             after.union(mBefore);
   225             ((View)view.getParent()).invalidate(
   226                     (int) Math.floor(after.left),
   227                     (int) Math.floor(after.top),
   228                     (int) Math.ceil(after.right),
   229                     (int) Math.ceil(after.bottom));
   230         }
   232         @Override
   233         public float getAlpha() {
   234             return mAlpha;
   235         }
   237         @Override
   238         public void setAlpha(float alpha) {
   239             if (mAlpha == alpha)
   240                 return;
   242             mAlpha = alpha;
   244             View view = mViewRef.get();
   245             if (view != null)
   246                 view.invalidate();
   247         }
   249         @Override
   250         public float getTranslationX() {
   251             return mTranslationX;
   252         }
   254         @Override
   255         public void setTranslationX(float translationX) {
   256             if (mTranslationX == translationX)
   257                 return;
   259             prepareForUpdate();
   260             mTranslationX = translationX;
   261             invalidateAfterUpdate();
   262         }
   264         @Override
   265         public float getTranslationY() {
   266             return mTranslationY;
   267         }
   269         @Override
   270         public void setTranslationY(float translationY) {
   271             if (mTranslationY == translationY)
   272                 return;
   274             prepareForUpdate();
   275             mTranslationY = translationY;
   276             invalidateAfterUpdate();
   277         }
   279         @Override
   280         public View getView() {
   281             return mViewRef.get();
   282         }
   284         @Override
   285         protected void applyTransformation(float interpolatedTime, Transformation t) {
   286             View view = mViewRef.get();
   287             if (view != null) {
   288                 t.setAlpha(mAlpha);
   289                 transformMatrix(t.getMatrix(), view);
   290             }
   291         }
   292     }
   294     private static class AnimatorProxyPostHC implements AnimatorProxyImpl {
   295         private WeakReference<View> mViewRef;
   297         public AnimatorProxyPostHC(View view) {
   298             mViewRef = new WeakReference<View>(view);
   299         }
   301         @Override
   302         public float getAlpha() {
   303             View view = mViewRef.get();
   304             if (view != null)
   305                 return view.getAlpha();
   307             return 1;
   308         }
   310         @Override
   311         public void setAlpha(float alpha) {
   312             View view = mViewRef.get();
   313             if (view != null)
   314                 view.setAlpha(alpha);
   315         }
   317         @Override
   318         public float getTranslationX() {
   319             View view = mViewRef.get();
   320             if (view != null)
   321                 return view.getTranslationX();
   323             return 0;
   324         }
   326         @Override
   327         public void setTranslationX(float translationX) {
   328             View view = mViewRef.get();
   329             if (view != null)
   330                 view.setTranslationX(translationX);
   331         }
   333         @Override
   334         public float getTranslationY() {
   335             View view = mViewRef.get();
   336             if (view != null)
   337                 return view.getTranslationY();
   339             return 0;
   340         }
   342         @Override
   343         public void setTranslationY(float translationY) {
   344             View view = mViewRef.get();
   345             if (view != null)
   346                 view.setTranslationY(translationY);
   347         }
   349         @Override
   350         public View getView() {
   351             return mViewRef.get();
   352         }
   353     }
   354 }

mercurial