TransitionAnimationView.java revision cf3d9f04955a8ec3cb405b8a4ddcaddcece2a245
1/* 2 * Copyright (C) 2010 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 com.android.contacts.widget; 17 18import android.animation.Animator; 19import android.animation.Animator.AnimatorListener; 20import android.animation.ObjectAnimator; 21import android.content.Context; 22import android.graphics.Bitmap; 23import android.graphics.Canvas; 24import android.graphics.Color; 25import android.graphics.drawable.BitmapDrawable; 26import android.util.AttributeSet; 27import android.view.View; 28import android.widget.FrameLayout; 29 30/** 31 * A container for a view that needs to have exit/enter animations when rebinding data. 32 * After rebinding the contents, the following call should be made (where child is the only visible) 33 * child 34 * <pre> 35 * TransitionAnimationView.startAnimation(child); 36 * </pre> 37 */ 38public class TransitionAnimationView extends FrameLayout implements AnimatorListener { 39 private View mPreviousStateView; 40 private Bitmap mPreviousStateBitmap; 41 private ObjectAnimator mPreviousAnimator; 42 43 public TransitionAnimationView(Context context) { 44 this(context, null, 0); 45 } 46 47 public TransitionAnimationView(Context context, AttributeSet attrs) { 48 this(context, attrs, 0); 49 } 50 51 public TransitionAnimationView(Context context, AttributeSet attrs, int defStyle) { 52 super(context, attrs, defStyle); 53 } 54 55 @Override 56 protected void onFinishInflate() { 57 super.onFinishInflate(); 58 mPreviousStateView = new View(getContext()); 59 mPreviousStateView.setVisibility(View.INVISIBLE); 60 mPreviousStateView.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, 61 LayoutParams.MATCH_PARENT)); 62 addView(mPreviousStateView); 63 } 64 65 @Override 66 protected void onDetachedFromWindow() { 67 super.onDetachedFromWindow(); 68 mPreviousStateView.setBackgroundDrawable(null); 69 if (mPreviousStateBitmap != null) { 70 mPreviousStateBitmap.recycle(); 71 mPreviousStateBitmap = null; 72 } 73 } 74 75 public void startTransition(View view, boolean closing) { 76 if (mPreviousAnimator != null && mPreviousAnimator.isRunning()) { 77 mPreviousAnimator.end(); 78 } 79 if (view.getVisibility() != View.VISIBLE) { 80 if (!closing) { 81 mPreviousAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, 0.0f, 1.0f); 82 mPreviousAnimator.start(); 83 } 84 } else if (closing) { 85 mPreviousAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, 1.0f, 0.0f); 86 mPreviousAnimator.start(); 87 } else { 88 if (view.getWidth() > 0 && view.getHeight() > 0) { 89 // Take a "screenshot" of the current state of the screen and show that on top 90 // of the real content. Then, fade that out. 91 mPreviousStateBitmap = Bitmap.createBitmap( 92 view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); 93 mPreviousStateView.setBackgroundDrawable( 94 new BitmapDrawable(getContext().getResources(), mPreviousStateBitmap)); 95 mPreviousStateView.setLayoutParams(view.getLayoutParams()); 96 mPreviousStateBitmap.eraseColor(Color.WHITE); 97 Canvas canvas = new Canvas(mPreviousStateBitmap); 98 view.draw(canvas); 99 canvas.setBitmap(null); 100 mPreviousStateView.setVisibility(View.VISIBLE); 101 102 mPreviousAnimator = 103 ObjectAnimator.ofFloat(mPreviousStateView, View.ALPHA, 1.0f, 0.0f); 104 mPreviousAnimator.start(); 105 } 106 } 107 } 108 109 @Override 110 public void onAnimationEnd(Animator animation) { 111 mPreviousStateView.setVisibility(View.INVISIBLE); 112 mPreviousStateView.setBackgroundDrawable(null); 113 mPreviousStateBitmap.recycle(); 114 mPreviousStateBitmap = null; 115 mPreviousAnimator = null; 116 } 117 118 @Override 119 public void onAnimationCancel(Animator animation) { 120 } 121 122 @Override 123 public void onAnimationStart(Animator animation) { 124 } 125 126 @Override 127 public void onAnimationRepeat(Animator animation) { 128 } 129} 130