1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.support.v4.view; 17 18import android.os.Build; 19import android.view.View; 20import android.view.animation.Interpolator; 21 22import java.lang.ref.WeakReference; 23import java.util.WeakHashMap; 24 25public final class ViewPropertyAnimatorCompat { 26 private static final String TAG = "ViewAnimatorCompat"; 27 private WeakReference<View> mView; 28 private Runnable mStartAction = null; 29 private Runnable mEndAction = null; 30 private int mOldLayerType = -1; 31 // HACK ALERT! Choosing this id knowing that the framework does not use it anywhere 32 // internally and apps should use ids higher than it 33 static final int LISTENER_TAG_ID = 0x7e000000; 34 35 ViewPropertyAnimatorCompat(View view) { 36 mView = new WeakReference<View>(view); 37 } 38 39 interface ViewPropertyAnimatorCompatImpl { 40 public void setDuration(ViewPropertyAnimatorCompat vpa, View view, long value); 41 public long getDuration(ViewPropertyAnimatorCompat vpa, View view); 42 public void setInterpolator(ViewPropertyAnimatorCompat vpa, View view, Interpolator value); 43 public Interpolator getInterpolator(ViewPropertyAnimatorCompat vpa, View view); 44 public void setStartDelay(ViewPropertyAnimatorCompat vpa, View view, long value); 45 public long getStartDelay(ViewPropertyAnimatorCompat vpa, View view); 46 public void alpha(ViewPropertyAnimatorCompat vpa, View view, float value); 47 public void alphaBy(ViewPropertyAnimatorCompat vpa, View view, float value); 48 public void rotation(ViewPropertyAnimatorCompat vpa, View view, float value); 49 public void rotationBy(ViewPropertyAnimatorCompat vpa, View view, float value); 50 public void rotationX(ViewPropertyAnimatorCompat vpa, View view, float value); 51 public void rotationXBy(ViewPropertyAnimatorCompat vpa, View view, float value); 52 public void rotationY(ViewPropertyAnimatorCompat vpa, View view, float value); 53 public void rotationYBy(ViewPropertyAnimatorCompat vpa, View view, float value); 54 public void scaleX(ViewPropertyAnimatorCompat vpa, View view, float value); 55 public void scaleXBy(ViewPropertyAnimatorCompat vpa, View view, float value); 56 public void scaleY(ViewPropertyAnimatorCompat vpa, View view, float value); 57 public void scaleYBy(ViewPropertyAnimatorCompat vpa, View view, float value); 58 public void cancel(ViewPropertyAnimatorCompat vpa, View view); 59 public void x(ViewPropertyAnimatorCompat vpa, View view, float value); 60 public void xBy(ViewPropertyAnimatorCompat vpa, View view, float value); 61 public void y(ViewPropertyAnimatorCompat vpa, View view, float value); 62 public void yBy(ViewPropertyAnimatorCompat vpa, View view, float value); 63 public void z(ViewPropertyAnimatorCompat vpa, View view, float value); 64 public void zBy(ViewPropertyAnimatorCompat vpa, View view, float value); 65 public void translationX(ViewPropertyAnimatorCompat vpa, View view, float value); 66 public void translationXBy(ViewPropertyAnimatorCompat vpa, View view, float value); 67 public void translationY(ViewPropertyAnimatorCompat vpa, View view, float value); 68 public void translationYBy(ViewPropertyAnimatorCompat vpa, View view, float value); 69 public void translationZ(ViewPropertyAnimatorCompat vpa, View view, float value); 70 public void translationZBy(ViewPropertyAnimatorCompat vpa, View view, float value); 71 public void start(ViewPropertyAnimatorCompat vpa, View view); 72 public void withLayer(ViewPropertyAnimatorCompat vpa, View view); 73 public void withStartAction(ViewPropertyAnimatorCompat vpa, View view, Runnable runnable); 74 public void withEndAction(ViewPropertyAnimatorCompat vpa, View view, Runnable runnable); 75 public void setListener(ViewPropertyAnimatorCompat vpa, View view, 76 ViewPropertyAnimatorListener listener); 77 public void setUpdateListener(ViewPropertyAnimatorCompat vpa, View view, 78 ViewPropertyAnimatorUpdateListener listener); 79 }; 80 81 static class BaseViewPropertyAnimatorCompatImpl implements ViewPropertyAnimatorCompatImpl { 82 WeakHashMap<View, Runnable> mStarterMap = null; 83 84 @Override 85 public void setDuration(ViewPropertyAnimatorCompat vpa, View view, long value) { 86 // noop on versions prior to ICS 87 } 88 89 @Override 90 public void alpha(ViewPropertyAnimatorCompat vpa, View view, float value) { 91 // noop on versions prior to ICS 92 postStartMessage(vpa, view); 93 } 94 95 @Override 96 public void translationX(ViewPropertyAnimatorCompat vpa, View view, float value) { 97 // noop on versions prior to ICS 98 postStartMessage(vpa, view); 99 } 100 101 @Override 102 public void translationY(ViewPropertyAnimatorCompat vpa, View view, float value) { 103 // noop on versions prior to ICS 104 postStartMessage(vpa, view); 105 } 106 107 @Override 108 public void withEndAction(ViewPropertyAnimatorCompat vpa, View view, Runnable runnable) { 109 vpa.mEndAction = runnable; 110 postStartMessage(vpa, view); 111 } 112 113 @Override 114 public long getDuration(ViewPropertyAnimatorCompat vpa, View view) { 115 return 0; 116 } 117 118 @Override 119 public void setInterpolator(ViewPropertyAnimatorCompat vpa, View view, Interpolator value) { 120 // noop on versions prior to ICS 121 } 122 123 @Override 124 public Interpolator getInterpolator(ViewPropertyAnimatorCompat vpa, View view) { 125 return null; 126 } 127 128 @Override 129 public void setStartDelay(ViewPropertyAnimatorCompat vpa, View view, long value) { 130 // noop on versions prior to ICS 131 } 132 133 @Override 134 public long getStartDelay(ViewPropertyAnimatorCompat vpa, View view) { 135 return 0; 136 } 137 138 @Override 139 public void alphaBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 140 // noop on versions prior to ICS 141 postStartMessage(vpa, view); 142 } 143 144 @Override 145 public void rotation(ViewPropertyAnimatorCompat vpa, View view, float value) { 146 // noop on versions prior to ICS 147 postStartMessage(vpa, view); 148 } 149 150 @Override 151 public void rotationBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 152 // noop on versions prior to ICS 153 postStartMessage(vpa, view); 154 } 155 156 @Override 157 public void rotationX(ViewPropertyAnimatorCompat vpa, View view, float value) { 158 // noop on versions prior to ICS 159 postStartMessage(vpa, view); 160 } 161 162 @Override 163 public void rotationXBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 164 // noop on versions prior to ICS 165 postStartMessage(vpa, view); 166 } 167 168 @Override 169 public void rotationY(ViewPropertyAnimatorCompat vpa, View view, float value) { 170 // noop on versions prior to ICS 171 postStartMessage(vpa, view); 172 } 173 174 @Override 175 public void rotationYBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 176 // noop on versions prior to ICS 177 postStartMessage(vpa, view); 178 } 179 180 @Override 181 public void scaleX(ViewPropertyAnimatorCompat vpa, View view, float value) { 182 // noop on versions prior to ICS 183 postStartMessage(vpa, view); 184 } 185 186 @Override 187 public void scaleXBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 188 // noop on versions prior to ICS 189 postStartMessage(vpa, view); 190 } 191 192 @Override 193 public void scaleY(ViewPropertyAnimatorCompat vpa, View view, float value) { 194 // noop on versions prior to ICS 195 postStartMessage(vpa, view); 196 } 197 198 @Override 199 public void scaleYBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 200 // noop on versions prior to ICS 201 postStartMessage(vpa, view); 202 } 203 204 @Override 205 public void cancel(ViewPropertyAnimatorCompat vpa, View view) { 206 // noop on versions prior to ICS 207 postStartMessage(vpa, view); 208 } 209 210 @Override 211 public void x(ViewPropertyAnimatorCompat vpa, View view, float value) { 212 // noop on versions prior to ICS 213 postStartMessage(vpa, view); 214 } 215 216 @Override 217 public void xBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 218 // noop on versions prior to ICS 219 postStartMessage(vpa, view); 220 } 221 222 @Override 223 public void y(ViewPropertyAnimatorCompat vpa, View view, float value) { 224 // noop on versions prior to ICS 225 postStartMessage(vpa, view); 226 } 227 228 @Override 229 public void yBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 230 // noop on versions prior to ICS 231 postStartMessage(vpa, view); 232 } 233 234 @Override 235 public void z(ViewPropertyAnimatorCompat vpa, View view, float value) { 236 // noop on versions prior to Lollipop 237 } 238 239 @Override 240 public void zBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 241 // noop on versions prior to Lollipop 242 } 243 244 @Override 245 public void translationXBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 246 // noop on versions prior to ICS 247 postStartMessage(vpa, view); 248 } 249 250 @Override 251 public void translationYBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 252 // noop on versions prior to ICS 253 postStartMessage(vpa, view); 254 } 255 256 @Override 257 public void translationZ(ViewPropertyAnimatorCompat vpa, View view, float value) { 258 // noop on versions prior to Lollipop 259 } 260 261 @Override 262 public void translationZBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 263 // noop on versions prior to Lollipop 264 } 265 266 @Override 267 public void start(ViewPropertyAnimatorCompat vpa, View view) { 268 removeStartMessage(view); 269 startAnimation(vpa, view); 270 } 271 272 @Override 273 public void withLayer(ViewPropertyAnimatorCompat vpa, View view) { 274 // noop on versions prior to ICS 275 } 276 277 @Override 278 public void withStartAction(ViewPropertyAnimatorCompat vpa, View view, Runnable runnable) { 279 vpa.mStartAction = runnable; 280 postStartMessage(vpa, view); 281 } 282 283 @Override 284 public void setListener(ViewPropertyAnimatorCompat vpa, View view, ViewPropertyAnimatorListener listener) { 285 view.setTag(LISTENER_TAG_ID, listener); 286 } 287 288 @Override 289 public void setUpdateListener(ViewPropertyAnimatorCompat vpa, View view, ViewPropertyAnimatorUpdateListener listener) { 290 // noop 291 } 292 293 private void startAnimation(ViewPropertyAnimatorCompat vpa, View view) { 294 Object listenerTag = view.getTag(LISTENER_TAG_ID); 295 ViewPropertyAnimatorListener listener = null; 296 if (listenerTag instanceof ViewPropertyAnimatorListener) { 297 listener = (ViewPropertyAnimatorListener) listenerTag; 298 } 299 Runnable startAction = vpa.mStartAction; 300 Runnable endAction = vpa.mEndAction; 301 vpa.mStartAction = null; 302 vpa.mEndAction = null; 303 if (startAction != null) { 304 startAction.run(); 305 } 306 if (listener != null) { 307 listener.onAnimationStart(view); 308 listener.onAnimationEnd(view); 309 } 310 if (endAction != null) { 311 endAction.run(); 312 } 313 if (mStarterMap != null) { 314 mStarterMap.remove(view); 315 } 316 } 317 318 class Starter implements Runnable { 319 WeakReference<View> mViewRef; 320 ViewPropertyAnimatorCompat mVpa; 321 322 private Starter(ViewPropertyAnimatorCompat vpa, View view) { 323 mViewRef = new WeakReference<View>(view); 324 mVpa = vpa; 325 } 326 327 @Override 328 public void run() { 329 final View view = mViewRef.get(); 330 if (view != null) { 331 startAnimation(mVpa, view); 332 } 333 } 334 }; 335 336 private void removeStartMessage(View view) { 337 Runnable starter = null; 338 if (mStarterMap != null) { 339 starter = mStarterMap.get(view); 340 if (starter != null) { 341 view.removeCallbacks(starter); 342 } 343 } 344 } 345 346 private void postStartMessage(ViewPropertyAnimatorCompat vpa, View view) { 347 Runnable starter = null; 348 if (mStarterMap != null) { 349 starter = mStarterMap.get(view); 350 } 351 if (starter == null) { 352 starter = new Starter(vpa, view); 353 if (mStarterMap == null) { 354 mStarterMap = new WeakHashMap<View, Runnable>(); 355 } 356 mStarterMap.put(view, starter); 357 } 358 view.removeCallbacks(starter); 359 view.post(starter); 360 } 361 362 } 363 364 static class ICSViewPropertyAnimatorCompatImpl extends BaseViewPropertyAnimatorCompatImpl { 365 WeakHashMap<View, Integer> mLayerMap = null; 366 367 @Override 368 public void setDuration(ViewPropertyAnimatorCompat vpa, View view, long value) { 369 ViewPropertyAnimatorCompatICS.setDuration(view, value); 370 } 371 372 @Override 373 public void alpha(ViewPropertyAnimatorCompat vpa, View view, float value) { 374 ViewPropertyAnimatorCompatICS.alpha(view, value); 375 } 376 377 @Override 378 public void translationX(ViewPropertyAnimatorCompat vpa, View view, float value) { 379 ViewPropertyAnimatorCompatICS.translationX(view, value); 380 } 381 382 @Override 383 public void translationY(ViewPropertyAnimatorCompat vpa, View view, float value) { 384 ViewPropertyAnimatorCompatICS.translationY(view, value); 385 } 386 387 @Override 388 public long getDuration(ViewPropertyAnimatorCompat vpa, View view) { 389 return ViewPropertyAnimatorCompatICS.getDuration(view); 390 } 391 392 @Override 393 public void setInterpolator(ViewPropertyAnimatorCompat vpa, View view, Interpolator value) { 394 ViewPropertyAnimatorCompatICS.setInterpolator(view, value); 395 } 396 397 @Override 398 public void setStartDelay(ViewPropertyAnimatorCompat vpa, View view, long value) { 399 ViewPropertyAnimatorCompatICS.setStartDelay(view, value); 400 } 401 402 @Override 403 public long getStartDelay(ViewPropertyAnimatorCompat vpa, View view) { 404 return ViewPropertyAnimatorCompatICS.getStartDelay(view); 405 } 406 407 @Override 408 public void alphaBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 409 ViewPropertyAnimatorCompatICS.alphaBy(view, value); 410 } 411 412 @Override 413 public void rotation(ViewPropertyAnimatorCompat vpa, View view, float value) { 414 ViewPropertyAnimatorCompatICS.rotation(view, value); 415 } 416 417 @Override 418 public void rotationBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 419 ViewPropertyAnimatorCompatICS.rotationBy(view, value); 420 } 421 422 @Override 423 public void rotationX(ViewPropertyAnimatorCompat vpa, View view, float value) { 424 ViewPropertyAnimatorCompatICS.rotationX(view, value); 425 } 426 427 @Override 428 public void rotationXBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 429 ViewPropertyAnimatorCompatICS.rotationXBy(view, value); 430 } 431 432 @Override 433 public void rotationY(ViewPropertyAnimatorCompat vpa, View view, float value) { 434 ViewPropertyAnimatorCompatICS.rotationY(view, value); 435 } 436 437 @Override 438 public void rotationYBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 439 ViewPropertyAnimatorCompatICS.rotationYBy(view, value); 440 } 441 442 @Override 443 public void scaleX(ViewPropertyAnimatorCompat vpa, View view, float value) { 444 ViewPropertyAnimatorCompatICS.scaleX(view, value); 445 } 446 447 @Override 448 public void scaleXBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 449 ViewPropertyAnimatorCompatICS.scaleXBy(view, value); 450 } 451 452 @Override 453 public void scaleY(ViewPropertyAnimatorCompat vpa, View view, float value) { 454 ViewPropertyAnimatorCompatICS.scaleY(view, value); 455 } 456 457 @Override 458 public void scaleYBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 459 ViewPropertyAnimatorCompatICS.scaleYBy(view, value); 460 } 461 462 @Override 463 public void cancel(ViewPropertyAnimatorCompat vpa, View view) { 464 ViewPropertyAnimatorCompatICS.cancel(view); 465 } 466 467 @Override 468 public void x(ViewPropertyAnimatorCompat vpa, View view, float value) { 469 ViewPropertyAnimatorCompatICS.x(view, value); 470 } 471 472 @Override 473 public void xBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 474 ViewPropertyAnimatorCompatICS.xBy(view, value); 475 } 476 477 @Override 478 public void y(ViewPropertyAnimatorCompat vpa, View view, float value) { 479 ViewPropertyAnimatorCompatICS.y(view, value); 480 } 481 482 @Override 483 public void yBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 484 ViewPropertyAnimatorCompatICS.yBy(view, value); 485 } 486 487 @Override 488 public void translationXBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 489 ViewPropertyAnimatorCompatICS.translationXBy(view, value); 490 } 491 492 @Override 493 public void translationYBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 494 ViewPropertyAnimatorCompatICS.translationYBy(view, value); 495 } 496 497 @Override 498 public void start(ViewPropertyAnimatorCompat vpa, View view) { 499 ViewPropertyAnimatorCompatICS.start(view); 500 } 501 502 @Override 503 public void setListener(ViewPropertyAnimatorCompat vpa, View view, ViewPropertyAnimatorListener listener) { 504 view.setTag(LISTENER_TAG_ID, listener); 505 ViewPropertyAnimatorCompatICS.setListener(view, new MyVpaListener(vpa)); 506 } 507 508 @Override 509 public void withEndAction(ViewPropertyAnimatorCompat vpa, View view, final Runnable runnable) { 510 ViewPropertyAnimatorCompatICS.setListener(view, new MyVpaListener(vpa)); 511 vpa.mEndAction = runnable; 512 } 513 514 @Override 515 public void withStartAction(ViewPropertyAnimatorCompat vpa, View view, final Runnable runnable) { 516 ViewPropertyAnimatorCompatICS.setListener(view, new MyVpaListener(vpa)); 517 vpa.mStartAction = runnable; 518 } 519 520 @Override 521 public void withLayer(ViewPropertyAnimatorCompat vpa, View view) { 522 vpa.mOldLayerType = ViewCompat.getLayerType(view); 523 ViewPropertyAnimatorCompatICS.setListener(view, new MyVpaListener(vpa)); 524 } 525 526 static class MyVpaListener implements ViewPropertyAnimatorListener { 527 ViewPropertyAnimatorCompat mVpa; 528 boolean mAnimEndCalled; 529 530 MyVpaListener(ViewPropertyAnimatorCompat vpa) { 531 mVpa = vpa; 532 } 533 534 @Override 535 public void onAnimationStart(View view) { 536 // Reset our end called flag, since this is a new animation... 537 mAnimEndCalled = false; 538 539 if (mVpa.mOldLayerType >= 0) { 540 ViewCompat.setLayerType(view, ViewCompat.LAYER_TYPE_HARDWARE, null); 541 } 542 if (mVpa.mStartAction != null) { 543 Runnable startAction = mVpa.mStartAction; 544 mVpa.mStartAction = null; 545 startAction.run(); 546 } 547 Object listenerTag = view.getTag(LISTENER_TAG_ID); 548 ViewPropertyAnimatorListener listener = null; 549 if (listenerTag instanceof ViewPropertyAnimatorListener) { 550 listener = (ViewPropertyAnimatorListener) listenerTag; 551 } 552 if (listener != null) { 553 listener.onAnimationStart(view); 554 } 555 } 556 557 @Override 558 public void onAnimationEnd(View view) { 559 if (mVpa.mOldLayerType >= 0) { 560 ViewCompat.setLayerType(view, mVpa.mOldLayerType, null); 561 mVpa.mOldLayerType = -1; 562 } 563 if (Build.VERSION.SDK_INT >= 16 || !mAnimEndCalled) { 564 // Pre-v16 seems to have a bug where onAnimationEnd is called 565 // twice, therefore we only dispatch on the first call 566 if (mVpa.mEndAction != null) { 567 Runnable endAction = mVpa.mEndAction; 568 mVpa.mEndAction = null; 569 endAction.run(); 570 } 571 Object listenerTag = view.getTag(LISTENER_TAG_ID); 572 ViewPropertyAnimatorListener listener = null; 573 if (listenerTag instanceof ViewPropertyAnimatorListener) { 574 listener = (ViewPropertyAnimatorListener) listenerTag; 575 } 576 if (listener != null) { 577 listener.onAnimationEnd(view); 578 } 579 mAnimEndCalled = true; 580 } 581 } 582 583 @Override 584 public void onAnimationCancel(View view) { 585 Object listenerTag = view.getTag(LISTENER_TAG_ID); 586 ViewPropertyAnimatorListener listener = null; 587 if (listenerTag instanceof ViewPropertyAnimatorListener) { 588 listener = (ViewPropertyAnimatorListener) listenerTag; 589 } 590 if (listener != null) { 591 listener.onAnimationCancel(view); 592 } 593 } 594 }; 595 } 596 597 static class JBViewPropertyAnimatorCompatImpl extends ICSViewPropertyAnimatorCompatImpl { 598 599 @Override 600 public void setListener(ViewPropertyAnimatorCompat vpa, View view, ViewPropertyAnimatorListener listener) { 601 ViewPropertyAnimatorCompatJB.setListener(view, listener); 602 } 603 604 @Override 605 public void withStartAction(ViewPropertyAnimatorCompat vpa, View view, Runnable runnable) { 606 ViewPropertyAnimatorCompatJB.withStartAction(view, runnable); 607 } 608 609 @Override 610 public void withEndAction(ViewPropertyAnimatorCompat vpa, View view, Runnable runnable) { 611 ViewPropertyAnimatorCompatJB.withEndAction(view, runnable); 612 } 613 614 @Override 615 public void withLayer(ViewPropertyAnimatorCompat vpa, View view) { 616 ViewPropertyAnimatorCompatJB.withLayer(view); 617 } 618 } 619 620 static class JBMr2ViewPropertyAnimatorCompatImpl extends JBViewPropertyAnimatorCompatImpl { 621 622 @Override 623 public Interpolator getInterpolator(ViewPropertyAnimatorCompat vpa, View view) { 624 return (Interpolator) ViewPropertyAnimatorCompatJellybeanMr2.getInterpolator(view); 625 } 626 } 627 628 static class KitKatViewPropertyAnimatorCompatImpl extends JBMr2ViewPropertyAnimatorCompatImpl { 629 @Override 630 public void setUpdateListener(ViewPropertyAnimatorCompat vpa, View view, ViewPropertyAnimatorUpdateListener listener) { 631 ViewPropertyAnimatorCompatKK.setUpdateListener(view, listener); 632 } 633 } 634 635 static class LollipopViewPropertyAnimatorCompatImpl extends KitKatViewPropertyAnimatorCompatImpl { 636 @Override 637 public void translationZ(ViewPropertyAnimatorCompat vpa, View view, float value) { 638 ViewPropertyAnimatorCompatLollipop.translationZ(view, value); 639 } 640 641 @Override 642 public void translationZBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 643 ViewPropertyAnimatorCompatLollipop.translationZBy(view, value); 644 } 645 646 @Override 647 public void z(ViewPropertyAnimatorCompat vpa, View view, float value) { 648 ViewPropertyAnimatorCompatLollipop.z(view, value); 649 } 650 651 @Override 652 public void zBy(ViewPropertyAnimatorCompat vpa, View view, float value) { 653 ViewPropertyAnimatorCompatLollipop.zBy(view, value); 654 } 655 } 656 657 static final ViewPropertyAnimatorCompatImpl IMPL; 658 static { 659 final int version = android.os.Build.VERSION.SDK_INT; 660 if (version >= 21) { 661 IMPL = new LollipopViewPropertyAnimatorCompatImpl(); 662 } else if (version >= 19) { 663 IMPL = new KitKatViewPropertyAnimatorCompatImpl(); 664 } else if (version >= 18) { 665 IMPL = new JBMr2ViewPropertyAnimatorCompatImpl(); 666 } else if (version >= 16) { 667 IMPL = new JBViewPropertyAnimatorCompatImpl(); 668 } else if (version >= 14) { 669 IMPL = new ICSViewPropertyAnimatorCompatImpl(); 670 } else { 671 IMPL = new BaseViewPropertyAnimatorCompatImpl(); 672 } 673 } 674 675 /** 676 * Sets the duration for the underlying animator that animates the requested properties. 677 * By default, the animator uses the default value for ValueAnimator. Calling this method 678 * will cause the declared value to be used instead. 679 * 680 * <p>Prior to API 14, this method will do nothing.</p> 681 * 682 * @param value The length of ensuing property animations, in milliseconds. The value 683 * cannot be negative. 684 * @return This object, allowing calls to methods in this class to be chained. 685 */ 686 public ViewPropertyAnimatorCompat setDuration(long value) { 687 View view; 688 if ((view = mView.get()) != null) { 689 IMPL.setDuration(this, view, value); 690 } 691 return this; 692 } 693 694 /** 695 * This method will cause the View's <code>alpha</code> property to be animated to the 696 * specified value. Animations already running on the property will be canceled. 697 * 698 * <p>Prior to API 14, this method will do nothing.</p> 699 * 700 * @param value The value to be animated to. 701 * @return This object, allowing calls to methods in this class to be chained. 702 */ 703 public ViewPropertyAnimatorCompat alpha(float value) { 704 View view; 705 if ((view = mView.get()) != null) { 706 IMPL.alpha(this, view, value); 707 } 708 return this; 709 } 710 711 /** 712 * This method will cause the View's <code>alpha</code> property to be animated by the 713 * specified value. Animations already running on the property will be canceled. 714 * 715 * <p>Prior to API 14, this method will do nothing.</p> 716 * 717 * @param value The amount to be animated by, as an offset from the current value. 718 * @return This object, allowing calls to methods in this class to be chained. 719 */ 720 public ViewPropertyAnimatorCompat alphaBy(float value) { 721 View view; 722 if ((view = mView.get()) != null) { 723 IMPL.alphaBy(this, view, value); 724 } 725 return this; 726 } 727 728 /** 729 * This method will cause the View's <code>translationX</code> property to be animated to the 730 * specified value. Animations already running on the property will be canceled. 731 * 732 * <p>Prior to API 14, this method will do nothing.</p> 733 * 734 * @param value The value to be animated to. 735 * @return This object, allowing calls to methods in this class to be chained. 736 */ 737 public ViewPropertyAnimatorCompat translationX(float value) { 738 View view; 739 if ((view = mView.get()) != null) { 740 IMPL.translationX(this, view, value); 741 } 742 return this; 743 } 744 745 /** 746 * This method will cause the View's <code>translationY</code> property to be animated to the 747 * specified value. Animations already running on the property will be canceled. 748 * 749 * <p>Prior to API 14, this method will do nothing.</p> 750 * 751 * @param value The value to be animated to. 752 * @return This object, allowing calls to methods in this class to be chained. 753 */ 754 public ViewPropertyAnimatorCompat translationY(float value) { 755 View view; 756 if ((view = mView.get()) != null) { 757 IMPL.translationY(this, view, value); 758 } 759 return this; 760 } 761 762 /** 763 * Specifies an action to take place when the next animation ends. The action is only 764 * run if the animation ends normally; if the ViewPropertyAnimator is canceled during 765 * that animation, the runnable will not run. 766 * This method, along with {@link #withStartAction(Runnable)}, is intended to help facilitate 767 * choreographing ViewPropertyAnimator animations with other animations or actions 768 * in the application. 769 * 770 * <p>For example, the following code animates a view to x=200 and then back to 0:</p> 771 * <pre> 772 * Runnable endAction = new Runnable() { 773 * public void run() { 774 * view.animate().x(0); 775 * } 776 * }; 777 * view.animate().x(200).withEndAction(endAction); 778 * </pre> 779 * 780 * <p>Prior to API 14, this method will run the action immediately.</p> 781 * 782 * <p>For API 14 and 15, this method will run by setting 783 * a listener on the ViewPropertyAnimatorCompat object and running the action 784 * in that listener's {@link ViewPropertyAnimatorListener#onAnimationEnd(View)} method.</p> 785 * 786 * @param runnable The action to run when the next animation ends. 787 * @return This object, allowing calls to methods in this class to be chained. 788 */ 789 public ViewPropertyAnimatorCompat withEndAction(Runnable runnable) { 790 View view; 791 if ((view = mView.get()) != null) { 792 IMPL.withEndAction(this, view, runnable); 793 } 794 return this; 795 } 796 797 /** 798 * Returns the current duration of property animations. If the duration was set on this 799 * object, that value is returned. Otherwise, the default value of the underlying Animator 800 * is returned. 801 * 802 * <p>Prior to API 14, this method will return 0.</p> 803 * 804 * @see #setDuration(long) 805 * @return The duration of animations, in milliseconds. 806 */ 807 public long getDuration() { 808 View view; 809 if ((view = mView.get()) != null) { 810 return IMPL.getDuration(this, view); 811 } else { 812 return 0; 813 } 814 } 815 816 /** 817 * Sets the interpolator for the underlying animator that animates the requested properties. 818 * By default, the animator uses the default interpolator for ValueAnimator. Calling this method 819 * will cause the declared object to be used instead. 820 * 821 * <p>Prior to API 14, this method will do nothing.</p> 822 * 823 * @param value The TimeInterpolator to be used for ensuing property animations. 824 * @return This object, allowing calls to methods in this class to be chained. 825 */ 826 public ViewPropertyAnimatorCompat setInterpolator(Interpolator value) { 827 View view; 828 if ((view = mView.get()) != null) { 829 IMPL.setInterpolator(this, view, value); 830 } 831 return this; 832 } 833 834 /** 835 * Returns the timing interpolator that this animation uses. 836 * 837 * <p>Prior to API 14, this method will return null.</p> 838 * 839 * @return The timing interpolator for this animation. 840 */ 841 public Interpolator getInterpolator() { 842 View view; 843 if ((view = mView.get()) != null) { 844 return IMPL.getInterpolator(this, view); 845 } 846 else return null; 847 } 848 849 /** 850 * Sets the startDelay for the underlying animator that animates the requested properties. 851 * By default, the animator uses the default value for ValueAnimator. Calling this method 852 * will cause the declared value to be used instead. 853 * 854 * <p>Prior to API 14, this method will do nothing.</p> 855 * 856 * @param value The delay of ensuing property animations, in milliseconds. The value 857 * cannot be negative. 858 * @return This object, allowing calls to methods in this class to be chained. 859 */ 860 public ViewPropertyAnimatorCompat setStartDelay(long value) { 861 View view; 862 if ((view = mView.get()) != null) { 863 IMPL.setStartDelay(this, view, value); 864 } 865 return this; 866 } 867 868 /** 869 * Returns the current startDelay of property animations. If the startDelay was set on this 870 * object, that value is returned. Otherwise, the default value of the underlying Animator 871 * is returned. 872 * 873 * <p>Prior to API 14, this method will return 0.</p> 874 * 875 * @see #setStartDelay(long) 876 * @return The startDelay of animations, in milliseconds. 877 */ 878 public long getStartDelay() { 879 View view; 880 if ((view = mView.get()) != null) { 881 return IMPL.getStartDelay(this, view); 882 } else { 883 return 0; 884 } 885 } 886 887 /** 888 * This method will cause the View's <code>rotation</code> property to be animated to the 889 * specified value. Animations already running on the property will be canceled. 890 * 891 * <p>Prior to API 14, this method will do nothing.</p> 892 * 893 * @param value The value to be animated to. 894 * @return This object, allowing calls to methods in this class to be chained. 895 */ 896 public ViewPropertyAnimatorCompat rotation(float value) { 897 View view; 898 if ((view = mView.get()) != null) { 899 IMPL.rotation(this, view, value); 900 } 901 return this; 902 } 903 904 /** 905 * This method will cause the View's <code>rotation</code> property to be animated by the 906 * specified value. Animations already running on the property will be canceled. 907 * 908 * <p>Prior to API 14, this method will do nothing.</p> 909 * 910 * @param value The amount to be animated by, as an offset from the current value. 911 * @return This object, allowing calls to methods in this class to be chained. 912 */ 913 public ViewPropertyAnimatorCompat rotationBy(float value) { 914 View view; 915 if ((view = mView.get()) != null) { 916 IMPL.rotationBy(this, view, value); 917 } 918 return this; 919 } 920 921 /** 922 * This method will cause the View's <code>rotationX</code> property to be animated to the 923 * specified value. Animations already running on the property will be canceled. 924 * 925 * <p>Prior to API 14, this method will do nothing.</p> 926 * 927 * @param value The value to be animated to. 928 * @return This object, allowing calls to methods in this class to be chained. 929 */ 930 public ViewPropertyAnimatorCompat rotationX(float value) { 931 View view; 932 if ((view = mView.get()) != null) { 933 IMPL.rotationX(this, view, value); 934 } 935 return this; 936 } 937 938 /** 939 * This method will cause the View's <code>rotationX</code> property to be animated by the 940 * specified value. Animations already running on the property will be canceled. 941 * 942 * <p>Prior to API 14, this method will do nothing.</p> 943 * 944 * @param value The amount to be animated by, as an offset from the current value. 945 * @return This object, allowing calls to methods in this class to be chained. 946 */ 947 public ViewPropertyAnimatorCompat rotationXBy(float value) { 948 View view; 949 if ((view = mView.get()) != null) { 950 IMPL.rotationXBy(this, view, value); 951 } 952 return this; 953 } 954 955 /** 956 * This method will cause the View's <code>rotationY</code> property to be animated to the 957 * specified value. Animations already running on the property will be canceled. 958 * 959 * <p>Prior to API 14, this method will do nothing.</p> 960 * 961 * @param value The value to be animated to. 962 * @return This object, allowing calls to methods in this class to be chained. 963 */ 964 public ViewPropertyAnimatorCompat rotationY(float value) { 965 View view; 966 if ((view = mView.get()) != null) { 967 IMPL.rotationY(this, view, value); 968 } 969 return this; 970 } 971 972 /** 973 * This method will cause the View's <code>rotationY</code> property to be animated by the 974 * specified value. Animations already running on the property will be canceled. 975 * 976 * <p>Prior to API 14, this method will do nothing.</p> 977 * 978 * @param value The amount to be animated by, as an offset from the current value. 979 * @return This object, allowing calls to methods in this class to be chained. 980 */ 981 public ViewPropertyAnimatorCompat rotationYBy(float value) { 982 View view; 983 if ((view = mView.get()) != null) { 984 IMPL.rotationYBy(this, view, value); 985 } 986 return this; 987 } 988 989 /** 990 * This method will cause the View's <code>scaleX</code> property to be animated to the 991 * specified value. Animations already running on the property will be canceled. 992 * 993 * <p>Prior to API 14, this method will do nothing.</p> 994 * 995 * @param value The value to be animated to. 996 * @return This object, allowing calls to methods in this class to be chained. 997 */ 998 public ViewPropertyAnimatorCompat scaleX(float value) { 999 View view; 1000 if ((view = mView.get()) != null) { 1001 IMPL.scaleX(this, view, value); 1002 } 1003 return this; 1004 } 1005 1006 /** 1007 * This method will cause the View's <code>scaleX</code> property to be animated by the 1008 * specified value. Animations already running on the property will be canceled. 1009 * 1010 * <p>Prior to API 14, this method will do nothing.</p> 1011 * 1012 * @param value The amount to be animated by, as an offset from the current value. 1013 * @return This object, allowing calls to methods in this class to be chained. 1014 */ 1015 public ViewPropertyAnimatorCompat scaleXBy(float value) { 1016 View view; 1017 if ((view = mView.get()) != null) { 1018 IMPL.scaleXBy(this, view, value); 1019 } 1020 return this; 1021 } 1022 1023 /** 1024 * This method will cause the View's <code>scaleY</code> property to be animated to the 1025 * specified value. Animations already running on the property will be canceled. 1026 * 1027 * <p>Prior to API 14, this method will do nothing.</p> 1028 * 1029 * @param value The value to be animated to. 1030 * @return This object, allowing calls to methods in this class to be chained. 1031 */ 1032 public ViewPropertyAnimatorCompat scaleY(float value) { 1033 View view; 1034 if ((view = mView.get()) != null) { 1035 IMPL.scaleY(this, view, value); 1036 } 1037 return this; 1038 } 1039 1040 /** 1041 * This method will cause the View's <code>scaleY</code> property to be animated by the 1042 * specified value. Animations already running on the property will be canceled. 1043 * 1044 * <p>Prior to API 14, this method will do nothing.</p> 1045 * 1046 * @param value The amount to be animated by, as an offset from the current value. 1047 * @return This object, allowing calls to methods in this class to be chained. 1048 */ 1049 public ViewPropertyAnimatorCompat scaleYBy(float value) { 1050 View view; 1051 if ((view = mView.get()) != null) { 1052 IMPL.scaleYBy(this, view, value); 1053 } 1054 return this; 1055 } 1056 1057 /** 1058 * Cancels all property animations that are currently running or pending. 1059 */ 1060 public void cancel() { 1061 View view; 1062 if ((view = mView.get()) != null) { 1063 IMPL.cancel(this, view); 1064 } 1065 } 1066 1067 /** 1068 * This method will cause the View's <code>x</code> property to be animated to the 1069 * specified value. Animations already running on the property will be canceled. 1070 * 1071 * <p>Prior to API 14, this method will do nothing.</p> 1072 * 1073 * @param value The value to be animated to. 1074 * @return This object, allowing calls to methods in this class to be chained. 1075 */ 1076 public ViewPropertyAnimatorCompat x(float value) { 1077 View view; 1078 if ((view = mView.get()) != null) { 1079 IMPL.x(this, view, value); 1080 } 1081 return this; 1082 } 1083 1084 /** 1085 * This method will cause the View's <code>x</code> property to be animated by the 1086 * specified value. Animations already running on the property will be canceled. 1087 * 1088 * <p>Prior to API 14, this method will do nothing.</p> 1089 * 1090 * @param value The amount to be animated by, as an offset from the current value. 1091 * @return This object, allowing calls to methods in this class to be chained. 1092 */ 1093 public ViewPropertyAnimatorCompat xBy(float value) { 1094 View view; 1095 if ((view = mView.get()) != null) { 1096 IMPL.xBy(this, view, value); 1097 } 1098 return this; 1099 } 1100 1101 /** 1102 * This method will cause the View's <code>y</code> property to be animated to the 1103 * specified value. Animations already running on the property will be canceled. 1104 * 1105 * <p>Prior to API 14, this method will do nothing.</p> 1106 * 1107 * @param value The value to be animated to. 1108 * @return This object, allowing calls to methods in this class to be chained. 1109 */ 1110 public ViewPropertyAnimatorCompat y(float value) { 1111 View view; 1112 if ((view = mView.get()) != null) { 1113 IMPL.y(this, view, value); 1114 } 1115 return this; 1116 } 1117 1118 /** 1119 * This method will cause the View's <code>y</code> property to be animated by the 1120 * specified value. Animations already running on the property will be canceled. 1121 * 1122 * <p>Prior to API 14, this method will do nothing.</p> 1123 * 1124 * @param value The amount to be animated by, as an offset from the current value. 1125 * @return This object, allowing calls to methods in this class to be chained. 1126 */ 1127 public ViewPropertyAnimatorCompat yBy(float value) { 1128 View view; 1129 if ((view = mView.get()) != null) { 1130 IMPL.yBy(this, view, value); 1131 } 1132 return this; 1133 } 1134 1135 /** 1136 * This method will cause the View's <code>translationX</code> property to be animated by the 1137 * specified value. Animations already running on the property will be canceled. 1138 * 1139 * <p>Prior to API 14, this method will do nothing.</p> 1140 * 1141 * @param value The amount to be animated by, as an offset from the current value. 1142 * @return This object, allowing calls to methods in this class to be chained. 1143 */ 1144 public ViewPropertyAnimatorCompat translationXBy(float value) { 1145 View view; 1146 if ((view = mView.get()) != null) { 1147 IMPL.translationXBy(this, view, value); 1148 } 1149 return this; 1150 } 1151 1152 /** 1153 * This method will cause the View's <code>translationY</code> property to be animated by the 1154 * specified value. Animations already running on the property will be canceled. 1155 * 1156 * <p>Prior to API 14, this method will do nothing.</p> 1157 * 1158 * @param value The amount to be animated by, as an offset from the current value. 1159 * @return This object, allowing calls to methods in this class to be chained. 1160 */ 1161 public ViewPropertyAnimatorCompat translationYBy(float value) { 1162 View view; 1163 if ((view = mView.get()) != null) { 1164 IMPL.translationYBy(this, view, value); 1165 } 1166 return this; 1167 } 1168 1169 /** 1170 * This method will cause the View's <code>translationZ</code> property to be animated by the 1171 * specified value. Animations already running on the property will be canceled. 1172 * 1173 * <p>Prior to API 21, this method will do nothing.</p> 1174 * 1175 * @param value The amount to be animated by, as an offset from the current value. 1176 * @return This object, allowing calls to methods in this class to be chained. 1177 */ 1178 public ViewPropertyAnimatorCompat translationZBy(float value) { 1179 View view; 1180 if ((view = mView.get()) != null) { 1181 IMPL.translationZBy(this, view, value); 1182 } 1183 return this; 1184 } 1185 1186 /** 1187 * This method will cause the View's <code>translationZ</code> property to be animated to the 1188 * specified value. Animations already running on the property will be canceled. 1189 * 1190 * <p>Prior to API 21, this method will do nothing.</p> 1191 * 1192 * @param value The amount to be animated by, as an offset from the current value. 1193 * @return This object, allowing calls to methods in this class to be chained. 1194 */ 1195 public ViewPropertyAnimatorCompat translationZ(float value) { 1196 View view; 1197 if ((view = mView.get()) != null) { 1198 IMPL.translationZ(this, view, value); 1199 } 1200 return this; 1201 } 1202 1203 /** 1204 * This method will cause the View's <code>z</code> property to be animated to the 1205 * specified value. Animations already running on the property will be canceled. 1206 * 1207 * <p>Prior to API 21, this method will do nothing.</p> 1208 * 1209 * @param value The amount to be animated by, as an offset from the current value. 1210 * @return This object, allowing calls to methods in this class to be chained. 1211 */ 1212 public ViewPropertyAnimatorCompat z(float value) { 1213 View view; 1214 if ((view = mView.get()) != null) { 1215 IMPL.z(this, view, value); 1216 } 1217 return this; 1218 } 1219 1220 /** 1221 * This method will cause the View's <code>z</code> property to be animated by the 1222 * specified value. Animations already running on the property will be canceled. 1223 * 1224 * <p>Prior to API 21, this method will do nothing.</p> 1225 * 1226 * @param value The amount to be animated by, as an offset from the current value. 1227 * @return This object, allowing calls to methods in this class to be chained. 1228 */ 1229 public ViewPropertyAnimatorCompat zBy(float value) { 1230 View view; 1231 if ((view = mView.get()) != null) { 1232 IMPL.zBy(this, view, value); 1233 } 1234 return this; 1235 } 1236 1237 /** 1238 * Starts the currently pending property animations immediately. Calling <code>start()</code> 1239 * is optional because all animations start automatically at the next opportunity. However, 1240 * if the animations are needed to start immediately and synchronously (not at the time when 1241 * the next event is processed by the hierarchy, which is when the animations would begin 1242 * otherwise), then this method can be used. 1243 * 1244 * <p>Prior to API 14, this method will do nothing.</p> 1245 */ 1246 public void start() { 1247 View view; 1248 if ((view = mView.get()) != null) { 1249 IMPL.start(this, view); 1250 } 1251 } 1252 1253 /** 1254 * The View associated with this ViewPropertyAnimator will have its 1255 * {@link ViewCompat#setLayerType(View, int, android.graphics.Paint) layer type} set to 1256 * {@link ViewCompat#LAYER_TYPE_HARDWARE} for the duration of the next animation. 1257 * As stated in the documentation for {@link ViewCompat#LAYER_TYPE_HARDWARE}, 1258 * the actual type of layer used internally depends on the runtime situation of the 1259 * view. If the activity and this view are hardware-accelerated, then the layer will be 1260 * accelerated as well. If the activity or the view is not accelerated, then the layer will 1261 * effectively be the same as {@link ViewCompat#LAYER_TYPE_SOFTWARE}. 1262 * 1263 * <p>This state is not persistent, either on the View or on this ViewPropertyAnimator: the 1264 * layer type of the View will be restored when the animation ends to what it was when this 1265 * method was called, and this setting on ViewPropertyAnimator is only valid for the next 1266 * animation. Note that calling this method and then independently setting the layer type of 1267 * the View (by a direct call to 1268 * {@link ViewCompat#setLayerType(View, int, android.graphics.Paint)}) will result in some 1269 * inconsistency, including having the layer type restored to its pre-withLayer() 1270 * value when the animation ends.</p> 1271 * 1272 * <p>Prior to API 14, this method will do nothing.</p> 1273 * 1274 * <p>For API 14 and 15, this method will run by setting 1275 * a listener on the ViewPropertyAnimatorCompat object, setting a hardware layer in 1276 * the listener's {@link ViewPropertyAnimatorListener#onAnimationStart(View)} method, 1277 * and then restoring the orignal layer type in the listener's 1278 * {@link ViewPropertyAnimatorListener#onAnimationEnd(View)} method.</p> 1279 * 1280 * @see View#setLayerType(int, android.graphics.Paint) 1281 * @return This object, allowing calls to methods in this class to be chained. 1282 */ 1283 public ViewPropertyAnimatorCompat withLayer() { 1284 View view; 1285 if ((view = mView.get()) != null) { 1286 IMPL.withLayer(this, view); 1287 } 1288 return this; 1289 } 1290 1291 /** 1292 * Specifies an action to take place when the next animation runs. If there is a 1293 * {@link #setStartDelay(long) startDelay} set on this ViewPropertyAnimator, then the 1294 * action will run after that startDelay expires, when the actual animation begins. 1295 * This method, along with {@link #withEndAction(Runnable)}, is intended to help facilitate 1296 * choreographing ViewPropertyAnimator animations with other animations or actions 1297 * in the application. 1298 * 1299 * <p>Prior to API 14, this method will run the action immediately.</p> 1300 * 1301 * <p>For API 14 and 15, this method will run by setting 1302 * a listener on the ViewPropertyAnimatorCompat object and running the action 1303 * in that listener's {@link ViewPropertyAnimatorListener#onAnimationStart(View)} method.</p> 1304 * 1305 * @param runnable The action to run when the next animation starts. 1306 * @return This object, allowing calls to methods in this class to be chained. 1307 */ 1308 public ViewPropertyAnimatorCompat withStartAction(Runnable runnable) { 1309 View view; 1310 if ((view = mView.get()) != null) { 1311 IMPL.withStartAction(this, view, runnable); 1312 } 1313 return this; 1314 } 1315 1316 /** 1317 * Sets a listener for events in the underlying Animators that run the property 1318 * animations. 1319 * 1320 * <p>Prior to API 14, this method will do nothing.</p> 1321 * 1322 * @param listener The listener to be called with AnimatorListener events. A value of 1323 * <code>null</code> removes any existing listener. 1324 * @return This object, allowing calls to methods in this class to be chained. 1325 */ 1326 public ViewPropertyAnimatorCompat setListener(ViewPropertyAnimatorListener listener) { 1327 View view; 1328 if ((view = mView.get()) != null) { 1329 IMPL.setListener(this, view, listener); 1330 } 1331 return this; 1332 } 1333 1334 /** 1335 * Sets a listener for update events in the underlying Animator that runs 1336 * the property animations. 1337 * 1338 * <p>Prior to API 19, this method will do nothing.</p> 1339 * 1340 * @param listener The listener to be called with update events. A value of 1341 * <code>null</code> removes any existing listener. 1342 * @return This object, allowing calls to methods in this class to be chained. 1343 */ 1344 public ViewPropertyAnimatorCompat setUpdateListener( 1345 ViewPropertyAnimatorUpdateListener listener) { 1346 View view; 1347 if ((view = mView.get()) != null) { 1348 IMPL.setUpdateListener(this, view, listener); 1349 } 1350 return this; 1351 } 1352} 1353