1990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 3990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 4990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License"); 5990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * you may not use this file except in compliance with the License. 6990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * You may obtain a copy of the License at 7990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 8990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * http://www.apache.org/licenses/LICENSE-2.0 9990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 10990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Unless required by applicable law or agreed to in writing, software 11990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS, 12990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * See the License for the specific language governing permissions and 14990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * limitations under the License. 15990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.fragment.app; 17990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 18990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertEquals; 19990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertFalse; 20990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertNotNull; 21990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertNull; 22990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertTrue; 23990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 24990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.app.Instrumentation; 25e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.os.Bundle; 26990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.os.Parcelable; 27990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.support.test.InstrumentationRegistry; 28990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.support.test.filters.MediumTest; 29990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.support.test.rule.ActivityTestRule; 30990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.support.test.runner.AndroidJUnit4; 31990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.util.Pair; 32e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.view.LayoutInflater; 33990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.View; 34e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.view.ViewGroup; 35990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.animation.Animation; 36e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.view.animation.AnimationUtils; 37990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.animation.TranslateAnimation; 38990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 39320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.annotation.AnimRes; 40320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.core.view.ViewCompat; 41320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.fragment.app.test.FragmentTestActivity; 42320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.fragment.test.R; 43320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikas 44990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport org.junit.Before; 45990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport org.junit.Rule; 46990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport org.junit.Test; 47990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport org.junit.runner.RunWith; 48990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 49e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport java.util.concurrent.CountDownLatch; 50e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport java.util.concurrent.TimeUnit; 51e62545fdf58881a2d0426285648f71ce9323ca15George Mount 52990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount@MediumTest 53990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount@RunWith(AndroidJUnit4.class) 54990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountpublic class FragmentAnimationTest { 55990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // These are pretend resource IDs for animators. We don't need real ones since we 56990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // load them by overriding onCreateAnimator 57990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @AnimRes 58990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static final int ENTER = 1; 59990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @AnimRes 60990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static final int EXIT = 2; 61990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @AnimRes 62990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static final int POP_ENTER = 3; 63990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @AnimRes 64990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static final int POP_EXIT = 4; 65990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 66990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Rule 67990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public ActivityTestRule<FragmentTestActivity> mActivityRule = 68990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class); 69990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 70990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private Instrumentation mInstrumentation; 71990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 72990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Before 73990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void setupContainer() { 74990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mInstrumentation = InstrumentationRegistry.getInstrumentation(); 75990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container); 76990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 77990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 78990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that adding and popping a Fragment uses the enter and popExit animators 79990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 80990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void addAnimators() throws Throwable { 81990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 82990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 83990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // One fragment with a view 84990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment = new AnimatorFragment(); 85990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 86990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 87990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .add(R.id.fragmentContainer, fragment) 88990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 89990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 90990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 91990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 92990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEnterPopExit(fragment); 93990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 94990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 95990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that removing and popping a Fragment uses the exit and popEnter animators 96990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 97990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void removeAnimators() throws Throwable { 98990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 99990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 100990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // One fragment with a view 101990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment = new AnimatorFragment(); 102990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit(); 103990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 104990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 105990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 106990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 107990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .remove(fragment) 108990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 109990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 110990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 111990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 112990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertExitPopEnter(fragment); 113990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 114990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 115990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that showing and popping a Fragment uses the enter and popExit animators 116990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 117990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void showAnimators() throws Throwable { 118990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 119990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 120990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // One fragment with a view 121990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment = new AnimatorFragment(); 122990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction().add(R.id.fragmentContainer, fragment).hide(fragment).commit(); 123990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 124990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 125990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 126990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 127990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .show(fragment) 128990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 129990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 130990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 131990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 132990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEnterPopExit(fragment); 133990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 134990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 135990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that hiding and popping a Fragment uses the exit and popEnter animators 136990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 137990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void hideAnimators() throws Throwable { 138990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 139990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 140990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // One fragment with a view 141990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment = new AnimatorFragment(); 142990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit(); 143990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 144990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 145990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 146990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 147990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .hide(fragment) 148990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 149990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 150990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 151990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 152990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertExitPopEnter(fragment); 153990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 154990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 155990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that attaching and popping a Fragment uses the enter and popExit animators 156990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 157990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void attachAnimators() throws Throwable { 158990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 159990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 160990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // One fragment with a view 161990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment = new AnimatorFragment(); 162990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction().add(R.id.fragmentContainer, fragment).detach(fragment).commit(); 163990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 164990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 165990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 166990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 167990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .attach(fragment) 168990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 169990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 170990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 171990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 172990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEnterPopExit(fragment); 173990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 174990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 175990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that detaching and popping a Fragment uses the exit and popEnter animators 176990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 177990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void detachAnimators() throws Throwable { 178990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 179990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 180990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // One fragment with a view 181990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment = new AnimatorFragment(); 182990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit(); 183990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 184990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 185990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 186990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 187990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .detach(fragment) 188990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 189990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 190990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 191990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 192990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertExitPopEnter(fragment); 193990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 194990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 195990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Replace should exit the existing fragments and enter the added fragment, then 196990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // popping should popExit the removed fragment and popEnter the added fragments 197990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 198990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void replaceAnimators() throws Throwable { 199990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 200990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 201990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // One fragment with a view 202990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment1 = new AnimatorFragment(); 203990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment2 = new AnimatorFragment(); 204990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 205990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .add(R.id.fragmentContainer, fragment1, "1") 206990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .add(R.id.fragmentContainer, fragment2, "2") 207990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 208990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 209990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 210990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment3 = new AnimatorFragment(); 211990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 212990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 213990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .replace(R.id.fragmentContainer, fragment3) 214990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 215990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 216990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 217990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 218990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment1, 1, false, EXIT); 219990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment2, 1, false, EXIT); 220990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment3, 1, true, ENTER); 221990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 222990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.popBackStack(); 223990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 224990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 225990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment3, 2, false, POP_EXIT); 226990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment replacement1 = (AnimatorFragment) fm.findFragmentByTag("1"); 227990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment replacement2 = (AnimatorFragment) fm.findFragmentByTag("1"); 228990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int expectedAnimations = replacement1 == fragment1 ? 2 : 1; 229990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(replacement1, expectedAnimations, true, POP_ENTER); 230990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(replacement2, expectedAnimations, true, POP_ENTER); 231990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 232990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 233990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that adding and popping a Fragment uses the enter and popExit animators, 234990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // but the animators are delayed when an entering Fragment is postponed. 235990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 236990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void postponedAddAnimators() throws Throwable { 237990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 238990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 239990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment = new AnimatorFragment(); 240990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.postponeEnterTransition(); 241990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 242990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 243990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .add(R.id.fragmentContainer, fragment) 244990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 245fda5be2466024a656152015c45a7681361d399bbGeorge Mount .setReorderingAllowed(true) 246990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 247990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 248990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 249990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertPostponed(fragment, 0); 250990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.startPostponedEnterTransition(); 251990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 252990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 253990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEnterPopExit(fragment); 254990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 255990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 256990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that removing and popping a Fragment uses the exit and popEnter animators, 257990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // but the animators are delayed when an entering Fragment is postponed. 258990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 259990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void postponedRemoveAnimators() throws Throwable { 260990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 261990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 262990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment = new AnimatorFragment(); 263990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit(); 264990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 265990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 266990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 267990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 268990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .remove(fragment) 269990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 270fda5be2466024a656152015c45a7681361d399bbGeorge Mount .setReorderingAllowed(true) 271990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 272990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 273990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 274990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertExitPostponedPopEnter(fragment); 275990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 276990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 277990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Ensure that adding and popping a Fragment is postponed in both directions 278990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // when the fragments have been marked for postponing. 279990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 280990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void postponedAddRemove() throws Throwable { 281990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 282990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 283990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment1 = new AnimatorFragment(); 284990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 285990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .add(R.id.fragmentContainer, fragment1) 286990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 287fda5be2466024a656152015c45a7681361d399bbGeorge Mount .setReorderingAllowed(true) 288990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 289990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 290990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 291990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment2 = new AnimatorFragment(); 292990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment2.postponeEnterTransition(); 293990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 294990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 295990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 296990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .replace(R.id.fragmentContainer, fragment2) 297990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 298fda5be2466024a656152015c45a7681361d399bbGeorge Mount .setReorderingAllowed(true) 299990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 300990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 301990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 302990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 303990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertPostponed(fragment2, 0); 304990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNotNull(fragment1.getView()); 305990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(View.VISIBLE, fragment1.getView().getVisibility()); 30615e593ea3575512d7072240d1db9d74fad8749a3George Mount assertEquals(1f, fragment1.getView().getAlpha(), 0f); 3074285a0db794444695fd0752e7bbc2ad95082043cGeorge Mount assertTrue(ViewCompat.isAttachedToWindow(fragment1.getView())); 308990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 309990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment2.startPostponedEnterTransition(); 310990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 311990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 312990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertExitPostponedPopEnter(fragment1); 313990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 314990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 315990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Popping a postponed transaction should result in no animators 316990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 317990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void popPostponed() throws Throwable { 318990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 319990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 320990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment1 = new AnimatorFragment(); 321990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 322990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .add(R.id.fragmentContainer, fragment1) 323fda5be2466024a656152015c45a7681361d399bbGeorge Mount .setReorderingAllowed(true) 324990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 325990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 326990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(0, fragment1.numAnimators); 327990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 328990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final AnimatorFragment fragment2 = new AnimatorFragment(); 329990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment2.postponeEnterTransition(); 330990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 331990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.beginTransaction() 332990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT) 333990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .replace(R.id.fragmentContainer, fragment2) 334990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 335fda5be2466024a656152015c45a7681361d399bbGeorge Mount .setReorderingAllowed(true) 336990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 337990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 338990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 339990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 340990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertPostponed(fragment2, 0); 341990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 342990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Now pop the postponed transaction 343990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.popBackStackImmediate(mActivityRule); 344990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 345990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNotNull(fragment1.getView()); 346990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(View.VISIBLE, fragment1.getView().getVisibility()); 34715e593ea3575512d7072240d1db9d74fad8749a3George Mount assertEquals(1f, fragment1.getView().getAlpha(), 0f); 3484285a0db794444695fd0752e7bbc2ad95082043cGeorge Mount assertTrue(ViewCompat.isAttachedToWindow(fragment1.getView())); 349990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertTrue(fragment1.isAdded()); 350990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 351990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNull(fragment2.getView()); 352990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFalse(fragment2.isAdded()); 353990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 354990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(0, fragment1.numAnimators); 355990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(0, fragment2.numAnimators); 356990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNull(fragment1.animation); 357990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNull(fragment2.animation); 358990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 359990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 360990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Make sure that if the state was saved while a Fragment was animating that its 361990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // state is proper after restoring. 362990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Test 363990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void saveWhileAnimatingAway() throws Throwable { 364990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentController fc1 = FragmentTestUtil.createController(mActivityRule); 3659268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount FragmentTestUtil.resume(mActivityRule, fc1, null); 366990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 367990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm1 = fc1.getSupportFragmentManager(); 368990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 369990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StrictViewFragment fragment1 = new StrictViewFragment(); 370990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment1.setLayoutId(R.layout.scene1); 371990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm1.beginTransaction() 372990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .add(R.id.fragmentContainer, fragment1, "1") 373990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 374990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 375990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 376990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StrictViewFragment fragment2 = new StrictViewFragment(); 377990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 378990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm1.beginTransaction() 379990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setCustomAnimations(0, 0, 0, R.anim.long_fade_out) 380990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .replace(R.id.fragmentContainer, fragment2, "2") 381990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addToBackStack(null) 382990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .commit(); 383990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mInstrumentation.runOnMainSync(new Runnable() { 384990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 385990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void run() { 386990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm1.executePendingTransactions(); 387990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 388990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount }); 389990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 390990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 391990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm1.popBackStack(); 392990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 393990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mInstrumentation.runOnMainSync(new Runnable() { 394990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 395990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void run() { 396990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm1.executePendingTransactions(); 397990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 398990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount }); 399990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 400990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Now fragment2 should be animating away 401990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFalse(fragment2.isAdded()); 402990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(fragment2, fm1.findFragmentByTag("2")); // still exists because it is animating 403990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 404990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Pair<Parcelable, FragmentManagerNonConfig> state = 4059268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount FragmentTestUtil.destroy(mActivityRule, fc1); 406990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 407990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentController fc2 = FragmentTestUtil.createController(mActivityRule); 4089268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount FragmentTestUtil.resume(mActivityRule, fc2, state); 409990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 410990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm2 = fc2.getSupportFragmentManager(); 411990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment fragment2restored = fm2.findFragmentByTag("2"); 412990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNull(fragment2restored); 413990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 414990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment fragment1restored = fm2.findFragmentByTag("1"); 415990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNotNull(fragment1restored); 416990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNotNull(fragment1restored.getView()); 417990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 418990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 419a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount // When an animation is running on a Fragment's View, the view shouldn't be 420a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount // prevented from being removed. There's no way to directly test this, so we have to 421a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount // test to see if the animation is still running. 422a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount @Test 423a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount public void clearAnimations() throws Throwable { 424a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 425a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount 426a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount final StrictViewFragment fragment1 = new StrictViewFragment(); 427a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount fm.beginTransaction() 428a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount .add(R.id.fragmentContainer, fragment1) 429fda5be2466024a656152015c45a7681361d399bbGeorge Mount .setReorderingAllowed(true) 430a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount .commit(); 431a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount FragmentTestUtil.waitForExecution(mActivityRule); 432a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount 433a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount final View fragmentView = fragment1.getView(); 434a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount 435a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount final TranslateAnimation xAnimation = new TranslateAnimation(0, 1000, 0, 0); 436a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount mActivityRule.runOnUiThread(new Runnable() { 437a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount @Override 438a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount public void run() { 439a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount fragmentView.startAnimation(xAnimation); 440a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount } 441a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount }); 442a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount 443a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount FragmentTestUtil.waitForExecution(mActivityRule); 444a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount FragmentTestUtil.popBackStackImmediate(mActivityRule); 445a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount mActivityRule.runOnUiThread(new Runnable() { 446a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount @Override 447a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount public void run() { 448a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount assertNull(fragmentView.getAnimation()); 449a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount } 450a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount }); 451a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount } 452a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount 453e62545fdf58881a2d0426285648f71ce9323ca15George Mount // When a view is animated out, is parent should be null after the animation completes 454e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Test 455e62545fdf58881a2d0426285648f71ce9323ca15George Mount public void parentNullAfterAnimation() throws Throwable { 456e62545fdf58881a2d0426285648f71ce9323ca15George Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 457e62545fdf58881a2d0426285648f71ce9323ca15George Mount 458e62545fdf58881a2d0426285648f71ce9323ca15George Mount final EndAnimationListenerFragment fragment1 = new EndAnimationListenerFragment(); 459e62545fdf58881a2d0426285648f71ce9323ca15George Mount fm.beginTransaction() 460e62545fdf58881a2d0426285648f71ce9323ca15George Mount .add(R.id.fragmentContainer, fragment1) 461e62545fdf58881a2d0426285648f71ce9323ca15George Mount .commit(); 462e62545fdf58881a2d0426285648f71ce9323ca15George Mount FragmentTestUtil.waitForExecution(mActivityRule); 463e62545fdf58881a2d0426285648f71ce9323ca15George Mount 464e62545fdf58881a2d0426285648f71ce9323ca15George Mount final EndAnimationListenerFragment fragment2 = new EndAnimationListenerFragment(); 465e62545fdf58881a2d0426285648f71ce9323ca15George Mount 466e62545fdf58881a2d0426285648f71ce9323ca15George Mount fm.beginTransaction() 467e62545fdf58881a2d0426285648f71ce9323ca15George Mount .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, 468e62545fdf58881a2d0426285648f71ce9323ca15George Mount android.R.anim.fade_in, android.R.anim.fade_out) 469e62545fdf58881a2d0426285648f71ce9323ca15George Mount .replace(R.id.fragmentContainer, fragment2) 470e62545fdf58881a2d0426285648f71ce9323ca15George Mount .addToBackStack(null) 471e62545fdf58881a2d0426285648f71ce9323ca15George Mount .commit(); 472e62545fdf58881a2d0426285648f71ce9323ca15George Mount 473e62545fdf58881a2d0426285648f71ce9323ca15George Mount FragmentTestUtil.waitForExecution(mActivityRule); 474e62545fdf58881a2d0426285648f71ce9323ca15George Mount 475e62545fdf58881a2d0426285648f71ce9323ca15George Mount assertTrue(fragment1.exitLatch.await(1, TimeUnit.SECONDS)); 476e62545fdf58881a2d0426285648f71ce9323ca15George Mount assertTrue(fragment2.enterLatch.await(1, TimeUnit.SECONDS)); 477e62545fdf58881a2d0426285648f71ce9323ca15George Mount 478e62545fdf58881a2d0426285648f71ce9323ca15George Mount mActivityRule.runOnUiThread(new Runnable() { 479e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 480e62545fdf58881a2d0426285648f71ce9323ca15George Mount public void run() { 481e62545fdf58881a2d0426285648f71ce9323ca15George Mount assertNotNull(fragment1.view); 482e62545fdf58881a2d0426285648f71ce9323ca15George Mount assertNotNull(fragment2.view); 483e62545fdf58881a2d0426285648f71ce9323ca15George Mount assertNull(fragment1.view.getParent()); 484e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 485e62545fdf58881a2d0426285648f71ce9323ca15George Mount }); 486e62545fdf58881a2d0426285648f71ce9323ca15George Mount 487e62545fdf58881a2d0426285648f71ce9323ca15George Mount // Now pop the transaction 488e62545fdf58881a2d0426285648f71ce9323ca15George Mount FragmentTestUtil.popBackStackImmediate(mActivityRule); 489e62545fdf58881a2d0426285648f71ce9323ca15George Mount 490e62545fdf58881a2d0426285648f71ce9323ca15George Mount assertTrue(fragment2.exitLatch.await(1, TimeUnit.SECONDS)); 491e62545fdf58881a2d0426285648f71ce9323ca15George Mount assertTrue(fragment1.enterLatch.await(1, TimeUnit.SECONDS)); 492e62545fdf58881a2d0426285648f71ce9323ca15George Mount 493e62545fdf58881a2d0426285648f71ce9323ca15George Mount mActivityRule.runOnUiThread(new Runnable() { 494e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 495e62545fdf58881a2d0426285648f71ce9323ca15George Mount public void run() { 496e62545fdf58881a2d0426285648f71ce9323ca15George Mount assertNull(fragment2.view.getParent()); 497e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 498e62545fdf58881a2d0426285648f71ce9323ca15George Mount }); 499e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 500e62545fdf58881a2d0426285648f71ce9323ca15George Mount 501990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void assertEnterPopExit(AnimatorFragment fragment) throws Throwable { 502990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment, 1, true, ENTER); 503990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 504990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 505990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.popBackStack(); 506990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 507990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 508990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment, 2, false, POP_EXIT); 509990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 510990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 511990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void assertExitPopEnter(AnimatorFragment fragment) throws Throwable { 512990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment, 1, false, EXIT); 513990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 514990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 515990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fm.popBackStack(); 516990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 517990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 518990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount AnimatorFragment replacement = (AnimatorFragment) fm.findFragmentByTag("1"); 519990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 520990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean isSameFragment = replacement == fragment; 521990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int expectedAnimators = isSameFragment ? 2 : 1; 522990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(replacement, expectedAnimators, true, POP_ENTER); 523990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 524990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 525990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void assertExitPostponedPopEnter(AnimatorFragment fragment) throws Throwable { 526990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment, 1, false, EXIT); 527990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 528990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.postponeEnterTransition(); 529990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.popBackStackImmediate(mActivityRule); 530990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 531990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertPostponed(fragment, 1); 532990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 533990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.startPostponedEnterTransition(); 534990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTestUtil.waitForExecution(mActivityRule); 535990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertFragmentAnimation(fragment, 2, true, POP_ENTER); 536990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 537990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 538990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void assertFragmentAnimation(AnimatorFragment fragment, int numAnimators, 539990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean isEnter, int animatorResourceId) throws InterruptedException { 540990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(numAnimators, fragment.numAnimators); 541990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(isEnter, fragment.enter); 542990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(animatorResourceId, fragment.resourceId); 543990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertNotNull(fragment.animation); 5444285a0db794444695fd0752e7bbc2ad95082043cGeorge Mount assertTrue(FragmentTestUtil.waitForAnimationEnd(1000, fragment.animation)); 545990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertTrue(fragment.animation.hasStarted()); 546990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 547990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 548990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void assertPostponed(AnimatorFragment fragment, int expectedAnimators) 549990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount throws InterruptedException { 550990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertTrue(fragment.mOnCreateViewCalled); 55115e593ea3575512d7072240d1db9d74fad8749a3George Mount assertEquals(View.VISIBLE, fragment.getView().getVisibility()); 55215e593ea3575512d7072240d1db9d74fad8749a3George Mount assertEquals(0f, fragment.getView().getAlpha(), 0f); 553990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount assertEquals(expectedAnimators, fragment.numAnimators); 554990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 555990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 556990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static class AnimatorFragment extends StrictViewFragment { 557990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public int numAnimators; 558990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public Animation animation; 559990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public boolean enter; 560990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public int resourceId; 561990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 562990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 563990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { 564990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (nextAnim == 0) { 565990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 566990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 567990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount this.numAnimators++; 568990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount this.animation = new TranslateAnimation(-10, 0, 0, 0); 569990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount this.animation.setDuration(1); 570990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount this.resourceId = nextAnim; 571990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount this.enter = enter; 572990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return this.animation; 573990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 574990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 575e62545fdf58881a2d0426285648f71ce9323ca15George Mount 576e62545fdf58881a2d0426285648f71ce9323ca15George Mount public static class EndAnimationListenerFragment extends StrictViewFragment { 577e62545fdf58881a2d0426285648f71ce9323ca15George Mount public View view; 578e62545fdf58881a2d0426285648f71ce9323ca15George Mount public final CountDownLatch enterLatch = new CountDownLatch(1); 579e62545fdf58881a2d0426285648f71ce9323ca15George Mount public final CountDownLatch exitLatch = new CountDownLatch(1); 580e62545fdf58881a2d0426285648f71ce9323ca15George Mount 581e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 582e62545fdf58881a2d0426285648f71ce9323ca15George Mount public View onCreateView(LayoutInflater inflater, ViewGroup container, 583e62545fdf58881a2d0426285648f71ce9323ca15George Mount Bundle savedInstanceState) { 584e62545fdf58881a2d0426285648f71ce9323ca15George Mount if (view != null) { 585e62545fdf58881a2d0426285648f71ce9323ca15George Mount return view; 586e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 587e62545fdf58881a2d0426285648f71ce9323ca15George Mount view = super.onCreateView(inflater, container, savedInstanceState); 588e62545fdf58881a2d0426285648f71ce9323ca15George Mount return view; 589e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 590e62545fdf58881a2d0426285648f71ce9323ca15George Mount 591e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 592e62545fdf58881a2d0426285648f71ce9323ca15George Mount public Animation onCreateAnimation(int transit, final boolean enter, int nextAnim) { 593e62545fdf58881a2d0426285648f71ce9323ca15George Mount if (nextAnim == 0) { 594e62545fdf58881a2d0426285648f71ce9323ca15George Mount return null; 595e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 596e62545fdf58881a2d0426285648f71ce9323ca15George Mount Animation anim = AnimationUtils.loadAnimation(getActivity(), nextAnim); 597e62545fdf58881a2d0426285648f71ce9323ca15George Mount if (anim != null) { 598e62545fdf58881a2d0426285648f71ce9323ca15George Mount anim.setAnimationListener(new Animation.AnimationListener() { 599e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 600e62545fdf58881a2d0426285648f71ce9323ca15George Mount public void onAnimationStart(Animation animation) { 601e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 602e62545fdf58881a2d0426285648f71ce9323ca15George Mount 603e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 604e62545fdf58881a2d0426285648f71ce9323ca15George Mount public void onAnimationEnd(Animation animation) { 605e62545fdf58881a2d0426285648f71ce9323ca15George Mount if (enter) { 606e62545fdf58881a2d0426285648f71ce9323ca15George Mount enterLatch.countDown(); 607e62545fdf58881a2d0426285648f71ce9323ca15George Mount } else { 608e62545fdf58881a2d0426285648f71ce9323ca15George Mount exitLatch.countDown(); 609e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 610e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 611e62545fdf58881a2d0426285648f71ce9323ca15George Mount 612e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 613e62545fdf58881a2d0426285648f71ce9323ca15George Mount public void onAnimationRepeat(Animation animation) { 614e62545fdf58881a2d0426285648f71ce9323ca15George Mount 615e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 616e62545fdf58881a2d0426285648f71ce9323ca15George Mount }); 617e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 618e62545fdf58881a2d0426285648f71ce9323ca15George Mount return anim; 619e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 620e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 621990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount} 622