FragmentTestActivity.java revision ac5fe7c617c66850fff75a9fce9979c6e5674b0f
1a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount/*
2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project
3a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount *
4a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * Licensed under the Apache License, Version 2.0 (the "License");
5a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * you may not use this file except in compliance with the License.
6a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * You may obtain a copy of the License at
7a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount *
8a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount *      http://www.apache.org/licenses/LICENSE-2.0
9a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount *
10a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * Unless required by applicable law or agreed to in writing, software
11a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * distributed under the License is distributed on an "AS IS" BASIS,
12a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * See the License for the specific language governing permissions and
14a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * limitations under the License.
15a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount */
16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.fragment.app.test;
17a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
18eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mountimport static org.junit.Assert.assertFalse;
19eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount
20a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.app.Activity;
212913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powellimport android.content.Context;
22a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnickimport android.content.Intent;
23a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Build.VERSION;
24a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Build.VERSION_CODES;
25a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Bundle;
26ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.Nullable;
27ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.fragment.test.R;
28ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.fragment.app.Fragment;
29ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.fragment.app.FragmentActivity;
30a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.Transition;
31a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.Transition.TransitionListener;
32a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.TransitionInflater;
33a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.LayoutInflater;
34a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.View;
35a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.ViewGroup;
36a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
37a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mountimport java.util.concurrent.CountDownLatch;
38a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mountimport java.util.concurrent.TimeUnit;
39a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
40a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount/**
412913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell * A simple activity used for Fragment Transitions and lifecycle event ordering
42a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount */
43a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountpublic class FragmentTestActivity extends FragmentActivity {
44eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    public final CountDownLatch onDestroyLatch = new CountDownLatch(1);
45eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount
46a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    @Override
47a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    public void onCreate(Bundle icicle) {
48a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        super.onCreate(icicle);
49a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        setContentView(R.layout.activity_content);
50eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        Intent intent = getIntent();
51eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        if (intent != null && intent.getBooleanExtra("finishEarly", false)) {
52eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            finish();
53eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            getSupportFragmentManager().beginTransaction()
54eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount                    .add(new AssertNotDestroyed(), "not destroyed")
55eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount                    .commit();
56eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        }
57eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    }
58eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount
59eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    @Override
60eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    protected void onDestroy() {
61eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        super.onDestroy();
62eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        onDestroyLatch.countDown();
63a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    }
64a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
65a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    public static class TestFragment extends Fragment {
66a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int ENTER = 0;
67a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int RETURN = 1;
68a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int EXIT = 2;
69a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int REENTER = 3;
70a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int SHARED_ELEMENT_ENTER = 4;
71a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int SHARED_ELEMENT_RETURN = 5;
72a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final int TRANSITION_COUNT = 6;
73a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
74a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final String LAYOUT_ID = "layoutId";
75a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final String TRANSITION_KEY = "transition_";
76a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private int mLayoutId = R.layout.fragment_start;
77a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private final int[] mTransitionIds = new int[] {
78a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
79a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
80a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
81a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
82a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.change_bounds,
83a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.change_bounds,
84a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        };
85a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        private final Object[] mListeners = new Object[TRANSITION_COUNT];
86a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
87a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public TestFragment() {
88a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
89a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                for (int i = 0; i < TRANSITION_COUNT; i++) {
90a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                    mListeners[i] = new TransitionCalledListener();
91a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                }
92a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
93a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
94a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
95a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static TestFragment create(int layoutId) {
96a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            TestFragment testFragment = new TestFragment();
97a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            testFragment.mLayoutId = layoutId;
98a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return testFragment;
99a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
100a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
101a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void clearTransitions() {
102a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
103a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                mTransitionIds[i] = 0;
104a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
105a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
106a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
107a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void clearNotifications() {
108a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
109a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                ((TransitionCalledListener)mListeners[i]).startLatch = new CountDownLatch(1);
110a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                ((TransitionCalledListener)mListeners[i]).endLatch = new CountDownLatch(1);
111a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
112a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
113a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
114a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
115a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onCreate(Bundle savedInstanceState) {
116a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onCreate(savedInstanceState);
117a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (savedInstanceState != null) {
118a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                mLayoutId = savedInstanceState.getInt(LAYOUT_ID, mLayoutId);
119a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                for (int i = 0; i < TRANSITION_COUNT; i++) {
120a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                    String key = TRANSITION_KEY + i;
121a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                    mTransitionIds[i] = savedInstanceState.getInt(key, mTransitionIds[i]);
122a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                }
123a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
124a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
125a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
126a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
127a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onSaveInstanceState(Bundle outState) {
128a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onSaveInstanceState(outState);
129a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            outState.putInt(LAYOUT_ID, mLayoutId);
130a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
131a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                String key = TRANSITION_KEY + i;
132a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                outState.putInt(key, mTransitionIds[i]);
133a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
134a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
135a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
136a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
137a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public View onCreateView(LayoutInflater inflater, ViewGroup container,
138a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                Bundle savedInstanceState) {
139a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return inflater.inflate(mLayoutId, container, false);
140a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
141a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
142a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @SuppressWarnings("deprecation")
143a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
144a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onAttach(Activity activity) {
145a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onAttach(activity);
146a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (VERSION.SDK_INT > VERSION_CODES.KITKAT) {
147a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setEnterTransition(loadTransition(ENTER));
148a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setReenterTransition(loadTransition(REENTER));
149a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setExitTransition(loadTransition(EXIT));
150a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setReturnTransition(loadTransition(RETURN));
151a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setSharedElementEnterTransition(loadTransition(SHARED_ELEMENT_ENTER));
152a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setSharedElementReturnTransition(loadTransition(SHARED_ELEMENT_RETURN));
153a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
154a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
155a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
156a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public boolean wasStartCalled(int transitionKey) {
157a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return ((TransitionCalledListener)mListeners[transitionKey]).startLatch.getCount() == 0;
158a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
159a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
160a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public boolean wasEndCalled(int transitionKey) {
161a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return ((TransitionCalledListener)mListeners[transitionKey]).endLatch.getCount() == 0;
162a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        }
163a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
164a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        public boolean waitForStart(int transitionKey)
165a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                throws InterruptedException {
166a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            TransitionCalledListener l = ((TransitionCalledListener)mListeners[transitionKey]);
167a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return l.startLatch.await(500,TimeUnit.MILLISECONDS);
168a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        }
169a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
170a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        public boolean waitForEnd(int transitionKey)
171a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                throws InterruptedException {
172a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            TransitionCalledListener l = ((TransitionCalledListener)mListeners[transitionKey]);
173a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return l.endLatch.await(500,TimeUnit.MILLISECONDS);
174a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
175a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
176a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private Transition loadTransition(int key) {
177a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            final int id = mTransitionIds[key];
178a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (id == 0) {
179a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                return null;
180a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
181a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            Transition transition = TransitionInflater.from(getActivity()).inflateTransition(id);
182a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            transition.addListener(((TransitionCalledListener)mListeners[key]));
183a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return transition;
184a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
185a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
186a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private class TransitionCalledListener implements TransitionListener {
187a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            public CountDownLatch startLatch = new CountDownLatch(1);
188a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            public CountDownLatch endLatch = new CountDownLatch(1);
189a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
190a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public TransitionCalledListener() {
191a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
192a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
193a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
194a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionStart(Transition transition) {
195a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                startLatch.countDown();
196a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
197a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
198a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
199a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionEnd(Transition transition) {
200a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                endLatch.countDown();
201a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
202a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
203a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
204a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionCancel(Transition transition) {
205a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
206a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
207a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
208a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionPause(Transition transition) {
209a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
210a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
211a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
212a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionResume(Transition transition) {
213a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
214a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
215a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    }
216a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
2172913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    public static class ParentFragment extends Fragment {
218c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        static final String CHILD_FRAGMENT_TAG = "childFragment";
2192913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public boolean wasAttachedInTime;
220c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
221c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        private boolean mRetainChild;
222a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
2232913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        @Override
2242913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public void onCreate(Bundle savedInstanceState) {
2252913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            super.onCreate(savedInstanceState);
226c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
227c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            ChildFragment f = getChildFragment();
228c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            if (f == null) {
229c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                f = new ChildFragment();
230c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                if (mRetainChild) {
231c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                    f.setRetainInstance(true);
232c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                }
233c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                getChildFragmentManager().beginTransaction().add(f, CHILD_FRAGMENT_TAG).commitNow();
234c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            }
235c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            wasAttachedInTime = f.attached;
236c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
237c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
238c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public ChildFragment getChildFragment() {
239c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            return (ChildFragment) getChildFragmentManager().findFragmentByTag(CHILD_FRAGMENT_TAG);
240c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
241c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
242c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public void setRetainChildInstance(boolean retainChild) {
243c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            mRetainChild = retainChild;
2442913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        }
2452913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    }
2462913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell
2472913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    public static class ChildFragment extends Fragment {
248c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        private OnAttachListener mOnAttachListener;
249c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
2502913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public boolean attached;
251a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public boolean onActivityResultCalled;
252a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public int onActivityResultRequestCode;
253a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public int onActivityResultResultCode;
254a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
2552913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        @Override
2562913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public void onAttach(Context activity) {
2572913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            super.onAttach(activity);
2582913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            attached = true;
259c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            if (mOnAttachListener != null) {
260c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                mOnAttachListener.onAttach(activity, this);
261c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            }
262c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
263c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
264c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public void setOnAttachListener(OnAttachListener listener) {
265c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            mOnAttachListener = listener;
266c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
267c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
268c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public interface OnAttachListener {
269c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            void onAttach(Context activity, ChildFragment fragment);
2702913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        }
271a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
272a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        @Override
273a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public void onActivityResult(int requestCode, int resultCode, Intent data) {
274a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultCalled = true;
275a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultRequestCode = requestCode;
276a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultResultCode = resultCode;
277a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        }
2782913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    }
279eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount
280eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    public static class AssertNotDestroyed extends Fragment {
281eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        @Override
282eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
283eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            super.onActivityCreated(savedInstanceState);
284eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) {
285eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount                assertFalse(getActivity().isDestroyed());
286eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            }
287eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        }
288eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    }
289a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount}
290