Visibility.java revision cba01b2310e78fc2114ceed285f4e134469ae62b
1faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/* 2faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Copyright (C) 2013 The Android Open Source Project 3faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 4faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * you may not use this file except in compliance with the License. 6faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * You may obtain a copy of the License at 7faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 8faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * http://www.apache.org/licenses/LICENSE-2.0 9faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 10faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Unless required by applicable law or agreed to in writing, software 11faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * See the License for the specific language governing permissions and 14faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * limitations under the License. 15faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 166ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 17d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haasepackage android.transition; 18faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 19ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport com.android.internal.R; 20ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 21faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.Animator; 22d6107a3170df61d9e776fcd5666acfc9135c6f16George Mountimport android.animation.AnimatorListenerAdapter; 23ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.content.Context; 24ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.content.res.TypedArray; 25d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.graphics.Bitmap; 26d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.graphics.Canvas; 27d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.graphics.drawable.BitmapDrawable; 28ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.util.AttributeSet; 29faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.View; 30faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewGroup; 31faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/** 32faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This transition tracks changes to the visibility of target views in the 33faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * start and end scenes. Visibility is determined not just by the 34faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * {@link View#setVisibility(int)} state of views, but also whether 35faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * views exist in the current view hierarchy. The class is intended to be a 36faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * utility for subclasses such as {@link Fade}, which use this visibility 37faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * information to determine the specific animations to run when visibility 3835a457a3bac0851a1fabd6cda58d1ea67f997b33Chet Haase * changes occur. Subclasses should implement one or both of the methods 39d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)}, 40d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)} or 41d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onAppear(ViewGroup, View, TransitionValues, TransitionValues)}, 42d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onDisappear(ViewGroup, View, TransitionValues, TransitionValues)}. 43faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 44faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haasepublic abstract class Visibility extends Transition { 45faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 466ceac2eafbb43dafd18bf547fee6fe51aee6b59bGeorge Mount static final String PROPNAME_VISIBILITY = "android:visibility:visibility"; 47faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private static final String PROPNAME_PARENT = "android:visibility:parent"; 48d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount private static final String PROPNAME_SCREEN_LOCATION = "android:visibility:screenLocation"; 49d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 5018ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount /** 5118ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount * Mode used in {@link #setMode(int)} to make the transition 5218ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount * operate on targets that are appearing. Maybe be combined with 53ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount * {@link #MODE_OUT} to target Visibility changes both in and out. 5418ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount */ 55ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount public static final int MODE_IN = 0x1; 5618ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount 5718ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount /** 5818ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount * Mode used in {@link #setMode(int)} to make the transition 5918ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount * operate on targets that are disappearing. Maybe be combined with 60ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount * {@link #MODE_IN} to target Visibility changes both in and out. 6118ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount */ 62ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount public static final int MODE_OUT = 0x2; 6318ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount 64af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase private static final String[] sTransitionProperties = { 65199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase PROPNAME_VISIBILITY, 66199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase }; 67faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 686ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private static class VisibilityInfo { 696ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase boolean visibilityChange; 706ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase boolean fadeIn; 716ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int startVisibility; 726ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int endVisibility; 7335a457a3bac0851a1fabd6cda58d1ea67f997b33Chet Haase ViewGroup startParent; 7435a457a3bac0851a1fabd6cda58d1ea67f997b33Chet Haase ViewGroup endParent; 756ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 766ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 77ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount private int mMode = MODE_IN | MODE_OUT; 7818ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount 79b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount private int mForcedStartVisibility = -1; 80b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount private int mForcedEndVisibility = -1; 81b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount 82ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public Visibility() {} 83ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 84ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public Visibility(Context context, AttributeSet attrs) { 85ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount super(context, attrs); 86ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VisibilityTransition); 873b2cd1d59fd894ac67a044c6c540fa69360a34a2Craig Mautner int mode = a.getInt(R.styleable.VisibilityTransition_transitionVisibilityMode, 0); 88ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount a.recycle(); 89ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount if (mode != 0) { 90ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount setMode(mode); 91ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 92ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 93ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 9418ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount /** 9518ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount * Changes the transition to support appearing and/or disappearing Views, depending 9618ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount * on <code>mode</code>. 9718ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount * 9818ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount * @param mode The behavior supported by this transition, a combination of 99ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount * {@link #MODE_IN} and {@link #MODE_OUT}. 1003b2cd1d59fd894ac67a044c6c540fa69360a34a2Craig Mautner * @attr ref android.R.styleable#VisibilityTransition_transitionVisibilityMode 10118ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount */ 10218ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount public void setMode(int mode) { 103ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount if ((mode & ~(MODE_IN | MODE_OUT)) != 0) { 104ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount throw new IllegalArgumentException("Only MODE_IN and MODE_OUT flags are allowed"); 10518ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount } 10618ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount mMode = mode; 10718ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount } 10818ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount 109ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount /** 110ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * Returns whether appearing and/or disappearing Views are supported. 111ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * 112ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * Returns whether appearing and/or disappearing Views are supported. A combination of 113ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount * {@link #MODE_IN} and {@link #MODE_OUT}. 1143b2cd1d59fd894ac67a044c6c540fa69360a34a2Craig Mautner * @attr ref android.R.styleable#VisibilityTransition_transitionVisibilityMode 115ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount */ 116ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public int getMode() { 117ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount return mMode; 118ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 119ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 120faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 121199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String[] getTransitionProperties() { 122199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return sTransitionProperties; 123199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 124199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 125b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount private void captureValues(TransitionValues transitionValues, int forcedVisibility) { 126b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount int visibility; 127b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount if (forcedVisibility != -1) { 128b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount visibility = forcedVisibility; 129b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } else { 130b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount visibility = transitionValues.view.getVisibility(); 131b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } 132d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase transitionValues.values.put(PROPNAME_VISIBILITY, visibility); 133d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase transitionValues.values.put(PROPNAME_PARENT, transitionValues.view.getParent()); 134d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int[] loc = new int[2]; 135d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount transitionValues.view.getLocationOnScreen(loc); 136d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount transitionValues.values.put(PROPNAME_SCREEN_LOCATION, loc); 137d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 138d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 139d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase @Override 140d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public void captureStartValues(TransitionValues transitionValues) { 141b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount captureValues(transitionValues, mForcedStartVisibility); 142d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 143d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 144199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 145d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public void captureEndValues(TransitionValues transitionValues) { 146b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount captureValues(transitionValues, mForcedEndVisibility); 147b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } 148b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount 149b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount /** @hide */ 150b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount @Override 151b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount public void forceVisibility(int visibility, boolean isStartValue) { 152b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount if (isStartValue) { 153b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount mForcedStartVisibility = visibility; 154b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } else { 155b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount mForcedEndVisibility = visibility; 156b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } 157faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 158faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 159199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 160199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns whether the view is 'visible' according to the given values 161199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * object. This is determined by testing the same properties in the values 162199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * object that are used to determine whether the object is appearing or 163199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * disappearing in the {@link 164d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Transition#createAnimator(ViewGroup, TransitionValues, TransitionValues)} 165199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * method. This method can be called by, for example, subclasses that want 166199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * to know whether the object is visible in the same way that Visibility 167199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * determines it for the actual animation. 168199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 169199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param values The TransitionValues object that holds the information by 170199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * which visibility is determined. 171199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return True if the view reference by <code>values</code> is visible, 172199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * false otherwise. 173199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 174199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public boolean isVisible(TransitionValues values) { 175199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (values == null) { 176199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return false; 177199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 178199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase int visibility = (Integer) values.values.get(PROPNAME_VISIBILITY); 179199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase View parent = (View) values.values.get(PROPNAME_PARENT); 180199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 181199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return visibility == View.VISIBLE && parent != null; 182199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 183199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1846ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private VisibilityInfo getVisibilityChangeInfo(TransitionValues startValues, 185faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues endValues) { 1867660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase final VisibilityInfo visInfo = new VisibilityInfo(); 1876ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.visibilityChange = false; 1886ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.fadeIn = false; 18931a217290cf376d0573fc36e21c8940987485019George Mount if (startValues != null && startValues.values.containsKey(PROPNAME_VISIBILITY)) { 1906ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY); 19135a457a3bac0851a1fabd6cda58d1ea67f997b33Chet Haase visInfo.startParent = (ViewGroup) startValues.values.get(PROPNAME_PARENT); 192faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1936ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.startVisibility = -1; 1946ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.startParent = null; 195faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 19631a217290cf376d0573fc36e21c8940987485019George Mount if (endValues != null && endValues.values.containsKey(PROPNAME_VISIBILITY)) { 1976ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY); 19835a457a3bac0851a1fabd6cda58d1ea67f997b33Chet Haase visInfo.endParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT); 199faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 2006ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.endVisibility = -1; 2016ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.endParent = null; 202faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 203faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (startValues != null && endValues != null) { 2046ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (visInfo.startVisibility == visInfo.endVisibility && 2056ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.startParent == visInfo.endParent) { 2066ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return visInfo; 207faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 2086ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (visInfo.startVisibility != visInfo.endVisibility) { 2096ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (visInfo.startVisibility == View.VISIBLE) { 2106ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.fadeIn = false; 2116ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.visibilityChange = true; 2126ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } else if (visInfo.endVisibility == View.VISIBLE) { 2136ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.fadeIn = true; 2146ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.visibilityChange = true; 215faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 216faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // no visibilityChange if going between INVISIBLE and GONE 2176ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } else if (visInfo.startParent != visInfo.endParent) { 2186ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (visInfo.endParent == null) { 2196ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.fadeIn = false; 2206ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.visibilityChange = true; 2216ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } else if (visInfo.startParent == null) { 2226ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.fadeIn = true; 2236ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.visibilityChange = true; 224faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 225faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 226faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 22779b2781aa763cbd770f690c16af4448139f37061George Mount } else if (startValues == null && visInfo.endVisibility == View.VISIBLE) { 2286ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.fadeIn = true; 2296ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.visibilityChange = true; 23079b2781aa763cbd770f690c16af4448139f37061George Mount } else if (endValues == null && visInfo.startVisibility == View.VISIBLE) { 2316ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.fadeIn = false; 2326ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase visInfo.visibilityChange = true; 233faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2346ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return visInfo; 235faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 236faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 237faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 238d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, 239faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues endValues) { 2406ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues); 24130da61d477bcb6cc7718f9516c444359352fe148George Mount if (visInfo.visibilityChange 24230da61d477bcb6cc7718f9516c444359352fe148George Mount && (visInfo.startParent != null || visInfo.endParent != null)) { 24330da61d477bcb6cc7718f9516c444359352fe148George Mount if (visInfo.fadeIn) { 24430da61d477bcb6cc7718f9516c444359352fe148George Mount return onAppear(sceneRoot, startValues, visInfo.startVisibility, 24530da61d477bcb6cc7718f9516c444359352fe148George Mount endValues, visInfo.endVisibility); 24630da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 24730da61d477bcb6cc7718f9516c444359352fe148George Mount return onDisappear(sceneRoot, startValues, visInfo.startVisibility, 24830da61d477bcb6cc7718f9516c444359352fe148George Mount endValues, visInfo.endVisibility 24930da61d477bcb6cc7718f9516c444359352fe148George Mount ); 250faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 251faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 252faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return null; 253faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 254faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 255faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 256d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * The default implementation of this method calls 257d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onAppear(ViewGroup, View, TransitionValues, TransitionValues)}. 258d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Subclasses should override this method or 259d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onAppear(ViewGroup, View, TransitionValues, TransitionValues)}. 260d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * if they need to create an Animator when targets appear. 261d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The method should only be called by the Visibility class; it is 262d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * not intended to be called from external classes. 263faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 264d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param sceneRoot The root of the transition hierarchy 265d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param startValues The target values in the start scene 266d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param startVisibility The target visibility in the start scene 267d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param endValues The target values in the end scene 268d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param endVisibility The target visibility in the end scene 269d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return An Animator to be started at the appropriate time in the 270d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * overall transition for this scene change. A null value means no animation 271d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should be run. 272faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 273d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Animator onAppear(ViewGroup sceneRoot, 2746ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues startValues, int startVisibility, 2756ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues endValues, int endVisibility) { 276ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount if ((mMode & MODE_IN) != MODE_IN || endValues == null) { 27718ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount return null; 27818ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount } 279e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout if (startValues == null) { 280e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout VisibilityInfo parentVisibilityInfo = null; 281e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout View endParent = (View) endValues.view.getParent(); 282e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout TransitionValues startParentValues = getMatchedTransitionValues(endParent, 283e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout false); 284e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout TransitionValues endParentValues = getTransitionValues(endParent, false); 285e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout parentVisibilityInfo = 286e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout getVisibilityChangeInfo(startParentValues, endParentValues); 287e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout if (parentVisibilityInfo.visibilityChange) { 288e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout return null; 289e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout } 290e988ee1eb2cc0cd345e42bcc549363a0e8c339aaCraig Stout } 291d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return onAppear(sceneRoot, endValues.view, startValues, endValues); 292d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 293d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 294d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 295d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * The default implementation of this method returns a null Animator. Subclasses should 296d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * override this method to make targets appear with the desired transition. The 297d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * method should only be called from 298d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)}. 299d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 300d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param sceneRoot The root of the transition hierarchy 301d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param view The View to make appear. This will be in the target scene's View hierarchy and 302d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * will be VISIBLE. 303d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param startValues The target values in the start scene 304d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param endValues The target values in the end scene 305d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return An Animator to be started at the appropriate time in the 306d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * overall transition for this scene change. A null value means no animation 307d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * should be run. 308d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 309d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, 310d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount TransitionValues endValues) { 3112ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase return null; 312faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 313faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 314faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 315d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Subclasses should override this method or 316d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onDisappear(ViewGroup, View, TransitionValues, TransitionValues)} 317d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * if they need to create an Animator when targets disappear. 318d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The method should only be called by the Visibility class; it is 319d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * not intended to be called from external classes. 320d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * <p> 321d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * The default implementation of this method attempts to find a View to use to call 322d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onDisappear(ViewGroup, View, TransitionValues, TransitionValues)}, 323d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * based on the situation of the View in the View hierarchy. For example, 324d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * if a View was simply removed from its parent, then the View will be added 325d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * into a {@link android.view.ViewGroupOverlay} and passed as the <code>view</code> 326d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * parameter in {@link #onDisappear(ViewGroup, View, TransitionValues, TransitionValues)}. 327d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * If a visible View is changed to be {@link View#GONE} or {@link View#INVISIBLE}, 328d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * then it can be used as the <code>view</code> and the visibility will be changed 329d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * to {@link View#VISIBLE} for the duration of the animation. However, if a View 330d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * is in a hierarchy which is also altering its visibility, the situation can be 331d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * more complicated. In general, if a view that is no longer in the hierarchy in 332d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the end scene still has a parent (so its parent hierarchy was removed, but it 333d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * was not removed from its parent), then it will be left alone to avoid side-effects from 334d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * improperly removing it from its parent. The only exception to this is if 335d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the previous {@link Scene} was {@link Scene#getSceneForLayout(ViewGroup, int, 336d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * android.content.Context) created from a layout resource file}, then it is considered 337d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * safe to un-parent the starting scene view in order to make it disappear.</p> 3386ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * 339d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param sceneRoot The root of the transition hierarchy 340d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param startValues The target values in the start scene 341d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param startVisibility The target visibility in the start scene 342d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param endValues The target values in the end scene 343d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param endVisibility The target visibility in the end scene 344d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return An Animator to be started at the appropriate time in the 345d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * overall transition for this scene change. A null value means no animation 346d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should be run. 347faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 348d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Animator onDisappear(ViewGroup sceneRoot, 3496ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues startValues, int startVisibility, 3506ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues endValues, int endVisibility) { 351ad88e1b1b2c57fa56bde68764b22240d145fa0efGeorge Mount if ((mMode & MODE_OUT) != MODE_OUT) { 35218ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount return null; 35318ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount } 35418ab79967ce8bcde4b1507164ac8186e5135622eGeorge Mount 355d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount View startView = (startValues != null) ? startValues.view : null; 356d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount View endView = (endValues != null) ? endValues.view : null; 357d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount View overlayView = null; 358d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount View viewToKeep = null; 359d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (endView == null || endView.getParent() == null) { 360d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (endView != null) { 361d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // endView was removed from its parent - add it to the overlay 362d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount overlayView = endView; 363d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } else if (startView != null) { 364d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // endView does not exist. Use startView only under certain 365d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // conditions, because placing a view in an overlay necessitates 366d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // it being removed from its current parent 367d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (startView.getParent() == null) { 368d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // no parent - safe to use 369d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount overlayView = startView; 370d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } else if (startView.getParent() instanceof View) { 371d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount View startParent = (View) startView.getParent(); 37279b2781aa763cbd770f690c16af4448139f37061George Mount TransitionValues startParentValues = getTransitionValues(startParent, true); 3739f1ac3976ea3aa08c20c06fa6678e367e1ed424dGeorge Mount TransitionValues endParentValues = getMatchedTransitionValues(startParent, 3749f1ac3976ea3aa08c20c06fa6678e367e1ed424dGeorge Mount true); 37579b2781aa763cbd770f690c16af4448139f37061George Mount VisibilityInfo parentVisibilityInfo = 37679b2781aa763cbd770f690c16af4448139f37061George Mount getVisibilityChangeInfo(startParentValues, endParentValues); 37779b2781aa763cbd770f690c16af4448139f37061George Mount if (!parentVisibilityInfo.visibilityChange) { 37879b2781aa763cbd770f690c16af4448139f37061George Mount overlayView = TransitionUtils.copyViewImage(sceneRoot, startView, 37979b2781aa763cbd770f690c16af4448139f37061George Mount startParent); 380d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } else if (startParent.getParent() == null) { 381d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount int id = startParent.getId(); 382d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount if (id != View.NO_ID && sceneRoot.findViewById(id) != null 383d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount && mCanRemoveViews) { 384d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // no parent, but its parent is unparented but the parent 385d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // hierarchy has been replaced by a new hierarchy with the same id 386d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // and it is safe to un-parent startView 387d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount overlayView = startView; 388d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 389d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 390d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 391d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 392d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } else { 393d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // visibility change 394d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (endVisibility == View.INVISIBLE) { 395d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount viewToKeep = endView; 396d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } else { 397d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // Becoming GONE 398d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (startView == endView) { 399d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount viewToKeep = endView; 400d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } else { 401d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount overlayView = startView; 402d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 403d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 404d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 405d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount final int finalVisibility = endVisibility; 406d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount final ViewGroup finalSceneRoot = sceneRoot; 407d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 408d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (overlayView != null) { 409d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // TODO: Need to do this for general case of adding to overlay 410d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int[] screenLoc = (int[]) startValues.values.get(PROPNAME_SCREEN_LOCATION); 411d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int screenX = screenLoc[0]; 412d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int screenY = screenLoc[1]; 413d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int[] loc = new int[2]; 414d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount sceneRoot.getLocationOnScreen(loc); 415d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft()); 416d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop()); 417d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount sceneRoot.getOverlay().add(overlayView); 418d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount Animator animator = onDisappear(sceneRoot, overlayView, startValues, endValues); 419d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (animator == null) { 420d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount sceneRoot.getOverlay().remove(overlayView); 421d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } else { 422d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount final View finalOverlayView = overlayView; 423d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount animator.addListener(new AnimatorListenerAdapter() { 424d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount @Override 425d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void onAnimationEnd(Animator animation) { 426d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount finalSceneRoot.getOverlay().remove(finalOverlayView); 427d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 428d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount }); 429d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 430d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return animator; 431d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 432d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 433d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (viewToKeep != null) { 434b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount int originalVisibility = -1; 435b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount final boolean isForcedVisibility = mForcedStartVisibility != -1 || 436b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount mForcedEndVisibility != -1; 437b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount if (!isForcedVisibility) { 438b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount originalVisibility = viewToKeep.getVisibility(); 439b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount viewToKeep.setVisibility(View.VISIBLE); 440b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } 441d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount Animator animator = onDisappear(sceneRoot, viewToKeep, startValues, endValues); 442b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount if (animator != null) { 443d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount final View finalViewToKeep = viewToKeep; 444d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount animator.addListener(new AnimatorListenerAdapter() { 445d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount boolean mCanceled = false; 446d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 447d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount @Override 448d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void onAnimationPause(Animator animation) { 449b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount if (!mCanceled && !isForcedVisibility) { 450d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount finalViewToKeep.setVisibility(finalVisibility); 451d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 452d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 453d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 454d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount @Override 455d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void onAnimationResume(Animator animation) { 456b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount if (!mCanceled && !isForcedVisibility) { 457d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount finalViewToKeep.setVisibility(View.VISIBLE); 458d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 459d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 460d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 461d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount @Override 462d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void onAnimationCancel(Animator animation) { 463d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mCanceled = true; 464d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 465d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 466d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount @Override 467d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void onAnimationEnd(Animator animation) { 468d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (!mCanceled) { 469b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount if (isForcedVisibility) { 470b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount finalViewToKeep.setTransitionAlpha(0); 471b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } else { 472b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount finalViewToKeep.setVisibility(finalVisibility); 473b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } 474d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 475d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 476d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount }); 477b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } else if (!isForcedVisibility) { 478b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount viewToKeep.setVisibility(originalVisibility); 479d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 480d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return animator; 481d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 482d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return null; 483d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 484d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 4854c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount @Override 4864c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) { 4874c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount if (oldValues == null && newValues == null) { 4884c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount return false; 4894c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount } 490cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount if (oldValues != null && newValues != null && 491cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount newValues.values.containsKey(PROPNAME_VISIBILITY) != 492cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount oldValues.values.containsKey(PROPNAME_VISIBILITY)) { 493cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount // The transition wasn't targeted in either the start or end, so it couldn't 494cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount // have changed. 495cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount return false; 496cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount } 497cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount VisibilityInfo changeInfo = getVisibilityChangeInfo(oldValues, newValues); 4984c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount return changeInfo.visibilityChange && (changeInfo.startVisibility == View.VISIBLE || 499cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount changeInfo.endVisibility == View.VISIBLE); 5004c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount } 5014c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount 502d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 503d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * The default implementation of this method returns a null Animator. Subclasses should 504d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * override this method to make targets disappear with the desired transition. The 505d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * method should only be called from 506d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)}. 507d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 508d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param sceneRoot The root of the transition hierarchy 509d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param view The View to make disappear. This will be in the target scene's View 510d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * hierarchy or in an {@link android.view.ViewGroupOverlay} and will be 511d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * VISIBLE. 512d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param startValues The target values in the start scene 513d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param endValues The target values in the end scene 514d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return An Animator to be started at the appropriate time in the 515d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * overall transition for this scene change. A null value means no animation 516d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * should be run. 517d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 518d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, 519d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount TransitionValues endValues) { 5206ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return null; 5216ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 522faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase} 523