1ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann/* 2ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * Copyright (C) 2012 The Android Open Source Project 3ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * 4ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License"); 5ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * you may not use this file except in compliance with the License. 6ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * You may obtain a copy of the License at 7ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * 8ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * http://www.apache.org/licenses/LICENSE-2.0 9ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * 10ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * Unless required by applicable law or agreed to in writing, software 11ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS, 12ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * See the License for the specific language governing permissions and 14ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * limitations under the License. 15ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann */ 16ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 17ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannpackage com.android.contacts.editor; 18ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 196f5557e3dc3cd12182026bdfea17b15d4d9b7dfcJosh Gargusimport com.android.contacts.util.SchedulingUtils; 2051f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus 21ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport com.google.common.collect.Lists; 22ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 23ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.animation.Animator; 24ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.animation.Animator.AnimatorListener; 25ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.animation.AnimatorListenerAdapter; 26ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.animation.AnimatorSet; 27ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.animation.ObjectAnimator; 28ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.view.View; 29ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.view.ViewGroup; 30ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.view.ViewParent; 31ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.widget.LinearLayout; 32ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 33ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport java.util.List; 34ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 35ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann/** 36ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * Configures animations for typical use-cases 37ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann */ 38ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannpublic class EditorAnimator { 39ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann private static EditorAnimator sInstance = new EditorAnimator(); 40ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 41ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public static EditorAnimator getInstance() { 42ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann return sInstance; 43ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 44ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 45ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann /** Private constructor for singleton */ 46ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann private EditorAnimator() { } 47ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 48ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann private AnimatorRunner mRunner = new AnimatorRunner(); 49ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 50ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void removeEditorView(final View victim) { 51ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mRunner.endOldAnimation(); 52ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final int offset = victim.getHeight(); 53ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 54ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<View> viewsToMove = getViewsBelowOf(victim); 55ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<Animator> animators = Lists.newArrayList(); 56ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 57ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Fade out 58ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ObjectAnimator fadeOutAnimator = 59ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann ObjectAnimator.ofFloat(victim, View.ALPHA, 1.0f, 0.0f); 60ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann fadeOutAnimator.setDuration(200); 61ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann animators.add(fadeOutAnimator); 62ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 63ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Translations 64ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann translateViews(animators, viewsToMove, 0.0f, -offset, 100, 200); 65ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 66ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mRunner.run(animators, new AnimatorListenerAdapter() { 67ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann @Override 68ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void onAnimationEnd(Animator animation) { 69ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Clean up: Remove all the translations 70ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann for (int i = 0; i < viewsToMove.size(); i++) { 71ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final View view = viewsToMove.get(i); 72ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann view.setTranslationY(0.0f); 73ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 74ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Remove our target view (if parent is null, we were run several times by quick 75ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // fingers. Just ignore) 76ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ViewGroup victimParent = (ViewGroup) victim.getParent(); 77ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann if (victimParent != null) { 78ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann victimParent.removeView(victim); 79ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 80ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 81ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann }); 82ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 83ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 84ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void expandOrganization(final View addOrganizationButton, 85ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ViewGroup organizationSectionViewContainer) { 86ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mRunner.endOldAnimation(); 87ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Make the new controls visible and do one layout pass (so that we can measure) 88ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann organizationSectionViewContainer.setVisibility(View.VISIBLE); 89ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann organizationSectionViewContainer.setAlpha(0.0f); 90ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann organizationSectionViewContainer.requestFocus(); 916f5557e3dc3cd12182026bdfea17b15d4d9b7dfcJosh Gargus SchedulingUtils.doAfterLayout(addOrganizationButton, new Runnable() { 92ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann @Override 93ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void run() { 94ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // How many pixels extra do we need? 95ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final int offset = organizationSectionViewContainer.getHeight() - 96ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann addOrganizationButton.getHeight(); 97ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 98ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<Animator> animators = Lists.newArrayList(); 99ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 100ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Fade out 101ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ObjectAnimator fadeOutAnimator = ObjectAnimator.ofFloat( 102ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann addOrganizationButton, View.ALPHA, 1.0f, 0.0f); 103ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann fadeOutAnimator.setDuration(200); 104ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann animators.add(fadeOutAnimator); 105ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 106ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Translations 107ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<View> viewsToMove = getViewsBelowOf(organizationSectionViewContainer); 108ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann translateViews(animators, viewsToMove, -offset, 0.0f, 0, 200); 109ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 110ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Fade in 111ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat( 112ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann organizationSectionViewContainer, View.ALPHA, 0.0f, 1.0f); 113ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann fadeInAnimator.setDuration(200); 114ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann fadeInAnimator.setStartDelay(200); 115ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann animators.add(fadeInAnimator); 116ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 117ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mRunner.run(animators); 118ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 119ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann }); 120ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 121ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 122ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void showAddFieldFooter(final View view) { 123ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mRunner.endOldAnimation(); 124ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann if (view.getVisibility() == View.VISIBLE) return; 125ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Make the new controls visible and do one layout pass (so that we can measure) 126ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann view.setVisibility(View.VISIBLE); 127ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann view.setAlpha(0.0f); 1286f5557e3dc3cd12182026bdfea17b15d4d9b7dfcJosh Gargus SchedulingUtils.doAfterLayout(view, new Runnable() { 129ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann @Override 130ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void run() { 131ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // How many pixels extra do we need? 132ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final int offset = view.getHeight(); 133ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 134ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<Animator> animators = Lists.newArrayList(); 135ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 136ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Translations 137ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<View> viewsToMove = getViewsBelowOf(view); 138ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann translateViews(animators, viewsToMove, -offset, 0.0f, 0, 200); 139ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 140ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Fade in 141ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat( 142ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann view, View.ALPHA, 0.0f, 1.0f); 143ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann fadeInAnimator.setDuration(200); 144ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann fadeInAnimator.setStartDelay(200); 145ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann animators.add(fadeInAnimator); 146ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 147ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mRunner.run(animators); 148ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 149ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann }); 150ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 151ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 152ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void hideAddFieldFooter(final View victim) { 153ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mRunner.endOldAnimation(); 154ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann if (victim.getVisibility() == View.GONE) return; 155ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final int offset = victim.getHeight(); 156ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 157ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<View> viewsToMove = getViewsBelowOf(victim); 158ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<Animator> animators = Lists.newArrayList(); 159ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 160ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Fade out 161ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ObjectAnimator fadeOutAnimator = 162ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann ObjectAnimator.ofFloat(victim, View.ALPHA, 1.0f, 0.0f); 163ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann fadeOutAnimator.setDuration(200); 164ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann animators.add(fadeOutAnimator); 165ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 166ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Translations 167ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann translateViews(animators, viewsToMove, 0.0f, -offset, 100, 200); 168ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 169ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Combine 170ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mRunner.run(animators, new AnimatorListenerAdapter() { 171ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann @Override 172ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void onAnimationEnd(Animator animation) { 173ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Clean up: Remove all the translations 174ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann for (int i = 0; i < viewsToMove.size(); i++) { 175ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final View view = viewsToMove.get(i); 176ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann view.setTranslationY(0.0f); 177ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 178ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 179ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann // Restore alpha (for next time), but hide the view for good now 180ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann victim.setAlpha(1.0f); 181ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann victim.setVisibility(View.GONE); 182ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 183ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann }); 184ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 185ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 186ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann /** 187ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * Creates a translation-animation for the given views 188ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann */ 189ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann private static void translateViews(List<Animator> animators, List<View> views, float fromY, 190ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann float toY, int startDelay, int duration) { 191ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann for (int i = 0; i < views.size(); i++) { 192ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final View child = views.get(i); 193ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ObjectAnimator translateAnimator = 194ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann ObjectAnimator.ofFloat(child, View.TRANSLATION_Y, fromY, toY); 195ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann translateAnimator.setStartDelay(startDelay); 196ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann translateAnimator.setDuration(duration); 197ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann animators.add(translateAnimator); 198ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 199ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 200ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 201ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann /** 202ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * Traverses up the view hierarchy and returns all views below this item. Stops 203ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * once a parent is not a vertical LinearLayout 2042e9ee9f15a1d928619a49ad259cdccbc8c7414dcChiao Cheng * 2052e9ee9f15a1d928619a49ad259cdccbc8c7414dcChiao Cheng * @return List of views that are below the given view. Empty list if parent of view is null. 206ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann */ 207ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann private static List<View> getViewsBelowOf(View view) { 208ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ViewGroup victimParent = (ViewGroup) view.getParent(); 209ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final List<View> result = Lists.newArrayList(); 2102e9ee9f15a1d928619a49ad259cdccbc8c7414dcChiao Cheng if (victimParent != null) { 2112e9ee9f15a1d928619a49ad259cdccbc8c7414dcChiao Cheng final int index = victimParent.indexOfChild(view); 2122e9ee9f15a1d928619a49ad259cdccbc8c7414dcChiao Cheng getViewsBelowOfRecursive(result, victimParent, index + 1); 2132e9ee9f15a1d928619a49ad259cdccbc8c7414dcChiao Cheng } 214ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann return result; 215ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 216ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 217ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann private static void getViewsBelowOfRecursive(List<View> result, ViewGroup container, 218ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann int index) { 219ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann for (int i = index; i < container.getChildCount(); i++) { 220ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann result.add(container.getChildAt(i)); 221ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 222ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 223ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final ViewParent parent = container.getParent(); 224ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann if (parent instanceof LinearLayout) { 225ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final LinearLayout parentLayout = (LinearLayout) parent; 226ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann if (parentLayout.getOrientation() == LinearLayout.VERTICAL) { 227ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann int containerIndex = parentLayout.indexOfChild(container); 228ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann getViewsBelowOfRecursive(result, parentLayout, containerIndex+1); 229ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 230ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 231ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 232ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 233ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann /** 234ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * Keeps a reference to the last animator, so that we can end that early if the user 235ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann * quickly pushes buttons. Removes the reference once the animation has finished 236ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann */ 237ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann /* package */ static class AnimatorRunner extends AnimatorListenerAdapter { 238ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann private Animator mLastAnimator; 239ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 240ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann @Override 241ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void onAnimationEnd(Animator animation) { 242ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mLastAnimator = null; 243ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 244ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 245ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void run(List<Animator> animators) { 246ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann run(animators, null); 247ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 248ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 249ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void run(List<Animator> animators, AnimatorListener listener) { 250ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann final AnimatorSet set = new AnimatorSet(); 251ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann set.playTogether(animators); 252ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann if (listener != null) set.addListener(listener); 253ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann set.addListener(this); 254ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mLastAnimator = set; 255ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann set.start(); 256ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 257ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann 258ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann public void endOldAnimation() { 259ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann if (mLastAnimator != null) { 260ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann mLastAnimator.end(); 261ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 262ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 263ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann } 264ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmann} 265