Protect use of onFindViewById for Fragment Transitions.
am: 1780bc94be
Change-Id: I8d6c2de7ffb7a12631c5bb8ba880e5a9f1939426
diff --git a/fragment/java/android/support/v4/app/FragmentTransition.java b/fragment/java/android/support/v4/app/FragmentTransition.java
index 71ac889..5e0d9e3 100644
--- a/fragment/java/android/support/v4/app/FragmentTransition.java
+++ b/fragment/java/android/support/v4/app/FragmentTransition.java
@@ -186,7 +186,10 @@
private static void configureTransitionsOptimized(FragmentManagerImpl fragmentManager,
int containerId, FragmentContainerTransition fragments,
View nonExistentView, ArrayMap<String, String> nameOverrides) {
- ViewGroup sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+ ViewGroup sceneRoot = null;
+ if (fragmentManager.mContainer.onHasView()) {
+ sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+ }
if (sceneRoot == null) {
return;
}
@@ -276,7 +279,10 @@
private static void configureTransitionsUnoptimized(FragmentManagerImpl fragmentManager,
int containerId, FragmentContainerTransition fragments,
View nonExistentView, ArrayMap<String, String> nameOverrides) {
- ViewGroup sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+ ViewGroup sceneRoot = null;
+ if (fragmentManager.mContainer.onHasView()) {
+ sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+ }
if (sceneRoot == null) {
return;
}
diff --git a/fragment/tests/java/android/support/v4/app/FragmentViewTests.java b/fragment/tests/java/android/support/v4/app/FragmentViewTests.java
index 296c3f8..521eb84 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentViewTests.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentViewTests.java
@@ -32,6 +32,7 @@
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.v4.app.test.FragmentTestActivity;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -942,6 +943,7 @@
// Ensure that non-optimized transactions are executed individually rather than together.
// This forces references from one fragment to another that should be executed earlier
// to work.
+ @Test
public void nonOptimizeTogether() throws Throwable {
FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
ViewGroup container = (ViewGroup)
@@ -973,6 +975,33 @@
assertNotNull(findViewById(R.id.textA));
}
+ // Ensure that there is no problem if the child fragment manager is used before
+ // the View has been added.
+ @Test
+ public void childFragmentManager() throws Throwable {
+ FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
+ ViewGroup container = (ViewGroup)
+ mActivityRule.getActivity().findViewById(R.id.fragmentContainer);
+ final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
+
+ final StrictViewFragment fragment1 = new ParentFragment();
+ fragment1.setLayoutId(R.layout.double_container);
+
+ fm.beginTransaction()
+ .add(R.id.fragmentContainer, fragment1)
+ .addToBackStack(null)
+ .commit();
+
+ FragmentTestUtil.executePendingTransactions(mActivityRule);
+
+ FragmentTestUtil.assertChildren(container, fragment1);
+ ViewGroup innerContainer = (ViewGroup)
+ fragment1.getView().findViewById(R.id.fragmentContainer1);
+
+ Fragment fragment2 = fragment1.getChildFragmentManager().findFragmentByTag("inner");
+ FragmentTestUtil.assertChildren(innerContainer, fragment2);
+ }
+
private View findViewById(int viewId) {
return mActivityRule.getActivity().findViewById(viewId);
}
@@ -996,4 +1025,25 @@
super.onViewCreated(view, savedInstanceState);
}
}
+
+ public static class ParentFragment extends StrictViewFragment {
+ public ParentFragment() {
+ setLayoutId(R.layout.double_container);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ final StrictViewFragment fragment2 = new StrictViewFragment();
+ fragment2.setLayoutId(R.layout.fragment_a);
+
+ getChildFragmentManager().beginTransaction()
+ .add(R.id.fragmentContainer1, fragment2, "inner")
+ .addToBackStack(null)
+ .commit();
+ getChildFragmentManager().executePendingTransactions();
+ return view;
+ }
+ }
}