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.

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

mercurial