From 08968232675aee0eaaf32bcc33282e2a0b6f1b86 Mon Sep 17 00:00:00 2001 From: Kejun Xia Date: Mon, 17 Aug 2015 23:35:37 +1000 Subject: [PATCH 1/7] Root fragment notify all nested fragments they are not managed by root fragment once the root fragment is restored --- ChangeLog.md | 3 +++ build.gradle | 2 +- .../shipdream/lib/android/mvc/view/MvcActivity.java | 10 ++++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 9b57bf4..624694e 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,6 @@ +Version: 1.1.7 +Once root fragment is restored, it should notify all nested fragments they are not managed by the root fragment any more + Version: 1.1.6 Fix issue that onViewReady is called with incorrect reason - RESTORE which should be FIRST_TIME when the fragment is a page and recreated by FragmentStatePagerAdapter diff --git a/build.gradle b/build.gradle index 82fb1f0..75d71f6 100644 --- a/build.gradle +++ b/build.gradle @@ -75,7 +75,7 @@ ext { version = [ major: 1, minor: 1, - patch : 6 + patch : 7 ] libGroup = 'com.shipdream' libVersion = "${version.major}.${version.minor}.${version.patch}" diff --git a/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java b/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java index 65e5635..5c01eb5 100644 --- a/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java +++ b/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java @@ -279,6 +279,8 @@ public void onViewStateRestored(Bundle savedInstanceState) { pendingOnViewReadyActions.clear(); } } + + notifyAllSubMvcFragmentsTheirStateIsManagedByMe(this, false); } /** @@ -322,7 +324,7 @@ public void onSaveInstanceState(Bundle outState) { isStateManagedByRootDelegateFragment = true; super.onSaveInstanceState(outState); - notifyAllSubMvcFragmentsTheirStateIsManagedByMe(this); + notifyAllSubMvcFragmentsTheirStateIsManagedByMe(this, true); long ts = System.currentTimeMillis(); Bundle mvcOutState = new Bundle(); @@ -336,7 +338,7 @@ public void onSaveInstanceState(Bundle outState) { * {@link StateManaged} objects those fragments holding will be saved into this root * fragment's outState bundle. */ - private void notifyAllSubMvcFragmentsTheirStateIsManagedByMe(Fragment fragment) { + private void notifyAllSubMvcFragmentsTheirStateIsManagedByMe(Fragment fragment, boolean selfManaged) { if (fragment != null) { List frags = fragment.getChildFragmentManager().getFragments(); if (frags != null) { @@ -344,10 +346,10 @@ private void notifyAllSubMvcFragmentsTheirStateIsManagedByMe(Fragment fragment) for (int i = 0; i < size; i++) { Fragment frag = frags.get(i); if (frag != null && frag.isAdded() && frag instanceof MvcFragment) { - ((MvcFragment) frag).isStateManagedByRootDelegateFragment = true; + ((MvcFragment) frag).isStateManagedByRootDelegateFragment = selfManaged; } - notifyAllSubMvcFragmentsTheirStateIsManagedByMe(frag); + notifyAllSubMvcFragmentsTheirStateIsManagedByMe(frag, selfManaged); } } } From 54916e73d6a50c28f99e76acb0a438d2d98afda7 Mon Sep 17 00:00:00 2001 From: Kejun Xia Date: Tue, 18 Aug 2015 19:42:23 +1000 Subject: [PATCH 2/7] Update robolectric to 3.0, Android support lib to 22.2.1, compile sdk to 23 --- build.gradle | 6 +++--- library/android-mvc-test/build.gradle | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 75d71f6..cf2c574 100644 --- a/build.gradle +++ b/build.gradle @@ -82,8 +82,8 @@ ext { shouldPublish = false androidMinSdkVersion = 14 - androidCompileSdkVersion = 22 - supportLibVersion = "22.2.0" + androidCompileSdkVersion = 23 + supportLibVersion = "22.2.1" androidTargetSdkVersion = androidCompileSdkVersion lib = [ androidMinSdk: 'com.google.android:android:4.0.1.2', @@ -95,7 +95,7 @@ ext { slf4jLog: "org.slf4j:slf4j-log4j12:$log4jVersion", logbackAndroidCore: "com.github.tony19:logback-android-core:$logbackAndroidVersion", logbackAndroidClassic: "com.github.tony19:logback-android-classic:$logbackAndroidVersion", - robolectric: "org.robolectric:robolectric:3.0-rc3" + robolectric: "org.robolectric:robolectric:3.0" ] } diff --git a/library/android-mvc-test/build.gradle b/library/android-mvc-test/build.gradle index 16834c7..f7215b1 100644 --- a/library/android-mvc-test/build.gradle +++ b/library/android-mvc-test/build.gradle @@ -26,6 +26,7 @@ dependencies { androidTestCompile 'com.android.support.test:runner:0.3' androidTestCompile 'com.android.support.test:rules:0.3' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2' + androidTestCompile "com.android.support:support-annotations:$rootProject.supportLibVersion" androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2' } From b96cef4269530d466ef0b1c0b697b72c493e0228 Mon Sep 17 00:00:00 2001 From: Kejun Xia Date: Tue, 18 Aug 2015 20:12:42 +1000 Subject: [PATCH 3/7] Fix bug that when a fragment pops out from back stack after the app restores, don't call onReturnForeground of the popping out fragment --- .../injection/TestInjectionAndLifeCycle.java | 33 +++++++++++++++++++ .../lib/android/mvc/view/MvcActivity.java | 1 + .../lib/android/mvc/view/MvcFragment.java | 6 +++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/injection/TestInjectionAndLifeCycle.java b/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/injection/TestInjectionAndLifeCycle.java index 86d44ab..a6114c5 100644 --- a/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/injection/TestInjectionAndLifeCycle.java +++ b/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/injection/TestInjectionAndLifeCycle.java @@ -162,4 +162,37 @@ public void test_should_delay_call_on_view_ready_on_sub_fragments_after_dependen onView(withId(R.id.textC)).check(matches(withText(""))); } + @Test + public void should_call_onViewReady_when_restored_fragment_pops_out() throws Throwable { + if (!isDontKeepActivities()) { + Log.i(getClass().getSimpleName(), "testLifeCyclesWhenKeepActivities not tested as Don't Keep Activities setting is disabled"); + return; + } + + //=============================> At A + lifeCycleValidatorA.expect(LifeCycle.onCreateNull, LifeCycle.onCreateViewNull, + LifeCycle.onViewCreatedNull, LifeCycle.onViewReadyFirstTime); + + //=============================> At B + navigationController.navigateTo(this, MvcTestActivityNavigation.Loc.B); + waitTest(); + lifeCycleValidatorA.expect(LifeCycle.onPushingToBackStack, LifeCycle.onDestroyView); + + pressHome(); + waitTest(1200); + + bringBack(); + waitTest(1200); + + //=============================> At A + navigationController.navigateBack(this); + waitTest(); + lifeCycleValidatorA.expect( + LifeCycle.onDestroy, + LifeCycle.onCreateNotNull, + LifeCycle.onCreateViewNotNull, + LifeCycle.onViewCreatedNotNull, + LifeCycle.onViewReadyRestore, + LifeCycle.onPoppedOutToFront); + } } diff --git a/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java b/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java index 5c01eb5..2090874 100644 --- a/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java +++ b/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java @@ -453,6 +453,7 @@ private void performBackNav(NavigationController.EventC2V.OnLocationBack event) currentFrag.registerOnViewReadyListener(new Runnable() { @Override public void run() { + currentFrag.isPoppingOut = true; currentFrag.onPoppedOutToFront(); unregisterOnViewReadyListener(this); } diff --git a/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcFragment.java b/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcFragment.java index 0765a67..5514809 100644 --- a/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcFragment.java +++ b/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcFragment.java @@ -83,6 +83,7 @@ public enum Reason { private boolean dependenciesInjected = false; boolean isStateManagedByRootDelegateFragment = false; + boolean isPoppingOut = false; /** * @return orientation before last orientation change. @@ -253,13 +254,16 @@ public void onStart() { private void checkWhetherReturnFromForeground() { if(fragmentJustCreatedFromSavedState) { - onReturnForeground(); + if (!isPoppingOut) { + onReturnForeground(); + } } else { if(!viewJustCreated) { onReturnForeground(); } } viewJustCreated = false; + isPoppingOut = false; fragmentJustCreatedFromSavedState = false; } From 1ce59626ee5bec791bb4ccd1876dfc89c7cd746e Mon Sep 17 00:00:00 2001 From: Kejun Xia Date: Tue, 18 Aug 2015 20:25:13 +1000 Subject: [PATCH 4/7] Add test for view pager life cycles --- .../viewpager/TestFragmentsInViewPager.java | 70 +++++++++++++++++++ .../mvc/view/viewpager/BaseTabFragment.java | 67 ++++++++++++++++++ .../mvc/view/viewpager/SubFragment.java | 11 +++ .../mvc/view/viewpager/TabFragmentA.java | 21 +++++- .../mvc/view/viewpager/TabFragmentB.java | 10 ++- .../mvc/view/viewpager/TabFragmentC.java | 10 ++- .../view/viewpager/ViewPagerHomeFragment.java | 57 +++++++++++++++ .../view/viewpager/ViewPagerTestActivity.java | 5 +- .../res/layout/fragment_view_pager_sub.xml | 29 ++++++++ 9 files changed, 273 insertions(+), 7 deletions(-) create mode 100644 library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/BaseTabFragment.java create mode 100644 library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/SubFragment.java create mode 100644 library/android-mvc-test/src/main/res/layout/fragment_view_pager_sub.xml diff --git a/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/viewpager/TestFragmentsInViewPager.java b/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/viewpager/TestFragmentsInViewPager.java index 8695bc4..1c8d0b3 100644 --- a/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/viewpager/TestFragmentsInViewPager.java +++ b/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/viewpager/TestFragmentsInViewPager.java @@ -16,7 +16,10 @@ package com.shipdream.lib.android.mvc.view.viewpager; +import android.util.Log; + import com.shipdream.lib.android.mvc.view.BaseTestCase; +import com.shipdream.lib.android.mvc.view.LifeCycle; import com.shipdream.lib.android.mvc.view.test.R; import org.junit.Test; @@ -56,5 +59,72 @@ public void should_restore_controller_of_tab_a_after_swipe_away_then_swipe_back_ onView(withText(TabFragmentA.RESTORE_TEXT)).check(matches(isDisplayed())); } + @Test + public void should_call_onViewReady_in_tab_fragments_when_restored_hosting_fragment_pops_out() throws Throwable { + if (!isDontKeepActivities()) { + Log.i(getClass().getSimpleName(), "TestFragmentsInViewPager not tested as Don't Keep Activities setting is disabled"); + return; + } + + //=============================> At Home + lifeCycleValidator.expect(LifeCycle.onCreateNull, LifeCycle.onCreateViewNull, + LifeCycle.onViewCreatedNull, LifeCycle.onViewReadyFirstTime); + + lifeCycleValidatorA.expect(LifeCycle.onCreateNull, LifeCycle.onCreateViewNull, + LifeCycle.onViewCreatedNull, LifeCycle.onViewReadyFirstTime); + + lifeCycleValidatorB.expect(LifeCycle.onCreateNull, LifeCycle.onCreateViewNull, + LifeCycle.onViewCreatedNull, LifeCycle.onViewReadyFirstTime); + + lifeCycleValidatorC.expect(); + + //=============================> At Sub Fragment + navigationController.navigateTo(this, SubFragment.class.getSimpleName()); + waitTest(1200); + + lifeCycleValidator.expect(LifeCycle.onPushingToBackStack, LifeCycle.onDestroyView); + lifeCycleValidatorA.expect(LifeCycle.onDestroyView); + lifeCycleValidatorB.expect(LifeCycle.onDestroyView); + lifeCycleValidatorC.expect(); + + pressHome(); + waitTest(1200); + bringBack(); + waitTest(1200); + lifeCycleValidator.expect( + LifeCycle.onDestroy, + LifeCycle.onCreateNotNull); + + lifeCycleValidatorA.expect( + LifeCycle.onDestroy, + LifeCycle.onCreateNotNull); + + lifeCycleValidatorB.expect( + LifeCycle.onDestroy, + LifeCycle.onCreateNotNull); + + lifeCycleValidatorC.expect(); + + //=============================> At A + navigationController.navigateBack(this); + waitTest(1200); + lifeCycleValidator.expect( + LifeCycle.onCreateViewNotNull, + LifeCycle.onViewCreatedNotNull, + LifeCycle.onViewReadyRestore, + LifeCycle.onPoppedOutToFront); + + lifeCycleValidatorA.expect( + LifeCycle.onCreateViewNotNull, + LifeCycle.onViewCreatedNotNull, + LifeCycle.onViewReadyRestore); + + lifeCycleValidatorB.expect( + LifeCycle.onCreateViewNotNull, + LifeCycle.onViewCreatedNotNull, + LifeCycle.onViewReadyRestore); + + lifeCycleValidatorC.expect(); + } } diff --git a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/BaseTabFragment.java b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/BaseTabFragment.java new file mode 100644 index 0000000..228f95b --- /dev/null +++ b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/BaseTabFragment.java @@ -0,0 +1,67 @@ +package com.shipdream.lib.android.mvc.view.viewpager; + +import android.os.Bundle; +import android.view.View; + +import com.shipdream.lib.android.mvc.view.MvcFragment; +import com.shipdream.lib.android.mvc.view.help.LifeCycleMonitor; + +public abstract class BaseTabFragment extends MvcFragment { + protected abstract LifeCycleMonitor getLifeCycleMonitor(); + + @Override + public void onViewReady(View view, Bundle savedInstanceState, MvcFragment.Reason reason) { + getLifeCycleMonitor().onCreateView(view, savedInstanceState); + getLifeCycleMonitor().onViewCreated(view, savedInstanceState); + super.onViewReady(view, savedInstanceState, reason); + getLifeCycleMonitor().onViewReady(view, savedInstanceState, reason); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getLifeCycleMonitor().onCreate(savedInstanceState); + } + + @Override + public void onResume() { + super.onResume(); + getLifeCycleMonitor().onResume(); + } + + @Override + protected void onReturnForeground() { + super.onReturnForeground(); + getLifeCycleMonitor().onReturnForeground(); + } + + @Override + protected void onPushingToBackStack() { + super.onPushingToBackStack(); + getLifeCycleMonitor().onPushingToBackStack(); + } + + @Override + protected void onPoppedOutToFront() { + super.onPoppedOutToFront(); + getLifeCycleMonitor().onPoppedOutToFront(); + } + + @Override + protected void onOrientationChanged(int lastOrientation, int currentOrientation) { + super.onOrientationChanged(lastOrientation, currentOrientation); + getLifeCycleMonitor().onOrientationChanged(lastOrientation, currentOrientation); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + getLifeCycleMonitor().onDestroyView(); + } + + @Override + public void onDestroy() { + getLifeCycleMonitor().onDestroy(); + super.onDestroy(); + } +} diff --git a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/SubFragment.java b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/SubFragment.java new file mode 100644 index 0000000..71b1e64 --- /dev/null +++ b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/SubFragment.java @@ -0,0 +1,11 @@ +package com.shipdream.lib.android.mvc.view.viewpager; + +import com.shipdream.lib.android.mvc.view.MvcFragment; +import com.shipdream.lib.android.mvc.view.test.R; + +public class SubFragment extends MvcFragment { + @Override + protected int getLayoutResId() { + return R.layout.fragment_view_pager_sub; + } +} diff --git a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentA.java b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentA.java index 818a49e..decb076 100644 --- a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentA.java +++ b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentA.java @@ -4,13 +4,15 @@ import android.view.View; import android.widget.TextView; -import com.shipdream.lib.android.mvc.view.MvcFragment; +import com.shipdream.lib.android.mvc.controller.NavigationController; +import com.shipdream.lib.android.mvc.view.MvcApp; +import com.shipdream.lib.android.mvc.view.help.LifeCycleMonitor; import com.shipdream.lib.android.mvc.view.test.R; import com.shipdream.lib.android.mvc.view.viewpager.controller.TabController; import javax.inject.Inject; -public class TabFragmentA extends MvcFragment { +public class TabFragmentA extends BaseTabFragment { static final String INIT_TEXT = "Tab A"; static final String RESTORE_TEXT = "Restored TabA"; @@ -19,11 +21,19 @@ public class TabFragmentA extends MvcFragment { private TextView textView; + @Inject + private NavigationController navigationController; + @Override protected int getLayoutResId() { return R.layout.fragment_view_pager_tab; } + @Override + protected LifeCycleMonitor getLifeCycleMonitor() { + return MvcApp.lifeCycleMonitorFactory.provideLifeCycleMonitorA(); + } + @Override public void onViewReady(View view, Bundle savedInstanceState, Reason reason) { super.onViewReady(view, savedInstanceState, reason); @@ -35,6 +45,13 @@ public void onViewReady(View view, Bundle savedInstanceState, Reason reason) { } else if (reason == Reason.RESTORE) { textView.setText(tabController.getModel().getName()); } + + textView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + navigationController.navigateTo(v, SubFragment.class.getSimpleName()); + } + }); } @Override diff --git a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentB.java b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentB.java index 3bfd34d..1a36b6d 100644 --- a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentB.java +++ b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentB.java @@ -4,10 +4,11 @@ import android.view.View; import android.widget.TextView; -import com.shipdream.lib.android.mvc.view.MvcFragment; +import com.shipdream.lib.android.mvc.view.MvcApp; +import com.shipdream.lib.android.mvc.view.help.LifeCycleMonitor; import com.shipdream.lib.android.mvc.view.test.R; -public class TabFragmentB extends MvcFragment { +public class TabFragmentB extends BaseTabFragment { private TextView textView; @Override @@ -15,6 +16,11 @@ protected int getLayoutResId() { return R.layout.fragment_view_pager_tab; } + @Override + protected LifeCycleMonitor getLifeCycleMonitor() { + return MvcApp.lifeCycleMonitorFactory.provideLifeCycleMonitorB(); + } + @Override public void onViewReady(View view, Bundle savedInstanceState, Reason reason) { super.onViewReady(view, savedInstanceState, reason); diff --git a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentC.java b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentC.java index 49a46a4..98cb223 100644 --- a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentC.java +++ b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/TabFragmentC.java @@ -4,10 +4,11 @@ import android.view.View; import android.widget.TextView; -import com.shipdream.lib.android.mvc.view.MvcFragment; +import com.shipdream.lib.android.mvc.view.MvcApp; +import com.shipdream.lib.android.mvc.view.help.LifeCycleMonitor; import com.shipdream.lib.android.mvc.view.test.R; -public class TabFragmentC extends MvcFragment { +public class TabFragmentC extends BaseTabFragment { private TextView textView; @Override @@ -15,6 +16,11 @@ protected int getLayoutResId() { return R.layout.fragment_view_pager_tab; } + @Override + protected LifeCycleMonitor getLifeCycleMonitor() { + return MvcApp.lifeCycleMonitorFactory.provideLifeCycleMonitorC(); + } + @Override public void onViewReady(View view, Bundle savedInstanceState, Reason reason) { super.onViewReady(view, savedInstanceState, reason); diff --git a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/ViewPagerHomeFragment.java b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/ViewPagerHomeFragment.java index 369dd62..cb2b54c 100644 --- a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/ViewPagerHomeFragment.java +++ b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/ViewPagerHomeFragment.java @@ -7,7 +7,9 @@ import android.support.v4.view.ViewPager; import android.view.View; +import com.shipdream.lib.android.mvc.view.MvcApp; import com.shipdream.lib.android.mvc.view.MvcFragment; +import com.shipdream.lib.android.mvc.view.help.LifeCycleMonitor; import com.shipdream.lib.android.mvc.view.test.R; public class ViewPagerHomeFragment extends MvcFragment { @@ -15,6 +17,8 @@ public class ViewPagerHomeFragment extends MvcFragment { private PagerAdapter pagerAdapter; + private LifeCycleMonitor lifeCycleMonitor = MvcApp.lifeCycleMonitorFactory.provideLifeCycleMonitor(); + @Override protected int getLayoutResId() { return R.layout.fragment_view_pager_home; @@ -22,7 +26,11 @@ protected int getLayoutResId() { @Override public void onViewReady(View view, Bundle savedInstanceState, Reason reason) { + lifeCycleMonitor.onCreateView(view, savedInstanceState); + lifeCycleMonitor.onViewCreated(view, savedInstanceState); super.onViewReady(view, savedInstanceState, reason); + lifeCycleMonitor.onViewReady(view, savedInstanceState, reason); + viewPager = (ViewPager) view.findViewById(R.id.viewpager); if (reason == Reason.FIRST_TIME || reason == Reason.RESTORE) { pagerAdapter = new PagerAdapter(getChildFragmentManager()); @@ -31,6 +39,55 @@ public void onViewReady(View view, Bundle savedInstanceState, Reason reason) { viewPager.setAdapter(pagerAdapter); } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + lifeCycleMonitor.onCreate(savedInstanceState); + } + + @Override + public void onResume() { + super.onResume(); + lifeCycleMonitor.onResume(); + } + + @Override + protected void onReturnForeground() { + super.onReturnForeground(); + lifeCycleMonitor.onReturnForeground(); + } + + @Override + protected void onPushingToBackStack() { + super.onPushingToBackStack(); + lifeCycleMonitor.onPushingToBackStack(); + } + + @Override + protected void onPoppedOutToFront() { + super.onPoppedOutToFront(); + lifeCycleMonitor.onPoppedOutToFront(); + } + + @Override + protected void onOrientationChanged(int lastOrientation, int currentOrientation) { + super.onOrientationChanged(lastOrientation, currentOrientation); + lifeCycleMonitor.onOrientationChanged(lastOrientation, currentOrientation); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + lifeCycleMonitor.onDestroyView(); + } + + @Override + public void onDestroy() { + lifeCycleMonitor.onDestroy(); + super.onDestroy(); + } + private class PagerAdapter extends FragmentStatePagerAdapter { private Class[] tabs = new Class[]{ TabFragmentA.class, diff --git a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/ViewPagerTestActivity.java b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/ViewPagerTestActivity.java index 90788af..61f8ee9 100644 --- a/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/ViewPagerTestActivity.java +++ b/library/android-mvc-test/src/main/java/com/shipdream/lib/android/mvc/view/viewpager/ViewPagerTestActivity.java @@ -23,6 +23,9 @@ public class ViewPagerTestActivity extends MvcActivity { @Override protected Class mapNavigationFragment(String locationId) { + if (locationId.equals(SubFragment.class.getSimpleName())) { + return SubFragment.class; + } return ViewPagerHomeFragment.class; } @@ -34,7 +37,7 @@ protected Class getDelegateFragmentClass() { public static class HomeFragment extends DelegateFragment { @Override protected void onStartUp() { - getNavigationController().navigateTo(this, "ViewPagerHomeFragment", null); + getNavigationController().navigateTo(this, ViewPagerHomeFragment.class.getSimpleName(), null); } } diff --git a/library/android-mvc-test/src/main/res/layout/fragment_view_pager_sub.xml b/library/android-mvc-test/src/main/res/layout/fragment_view_pager_sub.xml new file mode 100644 index 0000000..692d558 --- /dev/null +++ b/library/android-mvc-test/src/main/res/layout/fragment_view_pager_sub.xml @@ -0,0 +1,29 @@ + + + + + + + From a2e016c16d717029d600daa861887f131bc4f29d Mon Sep 17 00:00:00 2001 From: Kejun Xia Date: Tue, 18 Aug 2015 21:54:13 +1000 Subject: [PATCH 5/7] Fix issue that nested fragments of popping out fragment won't call onReturnFromBackground incorrectly --- build.gradle | 2 +- .../injection/TestInjectionAndLifeCycle.java | 33 ------------------- .../lib/android/mvc/view/MvcActivity.java | 23 ++++++++++++- 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/build.gradle b/build.gradle index cf2c574..b75f04e 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ ext { shouldPublish = false androidMinSdkVersion = 14 - androidCompileSdkVersion = 23 + androidCompileSdkVersion = 22 supportLibVersion = "22.2.1" androidTargetSdkVersion = androidCompileSdkVersion lib = [ diff --git a/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/injection/TestInjectionAndLifeCycle.java b/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/injection/TestInjectionAndLifeCycle.java index a6114c5..86d44ab 100644 --- a/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/injection/TestInjectionAndLifeCycle.java +++ b/library/android-mvc-test/src/androidTest/java/com/shipdream/lib/android/mvc/view/injection/TestInjectionAndLifeCycle.java @@ -162,37 +162,4 @@ public void test_should_delay_call_on_view_ready_on_sub_fragments_after_dependen onView(withId(R.id.textC)).check(matches(withText(""))); } - @Test - public void should_call_onViewReady_when_restored_fragment_pops_out() throws Throwable { - if (!isDontKeepActivities()) { - Log.i(getClass().getSimpleName(), "testLifeCyclesWhenKeepActivities not tested as Don't Keep Activities setting is disabled"); - return; - } - - //=============================> At A - lifeCycleValidatorA.expect(LifeCycle.onCreateNull, LifeCycle.onCreateViewNull, - LifeCycle.onViewCreatedNull, LifeCycle.onViewReadyFirstTime); - - //=============================> At B - navigationController.navigateTo(this, MvcTestActivityNavigation.Loc.B); - waitTest(); - lifeCycleValidatorA.expect(LifeCycle.onPushingToBackStack, LifeCycle.onDestroyView); - - pressHome(); - waitTest(1200); - - bringBack(); - waitTest(1200); - - //=============================> At A - navigationController.navigateBack(this); - waitTest(); - lifeCycleValidatorA.expect( - LifeCycle.onDestroy, - LifeCycle.onCreateNotNull, - LifeCycle.onCreateViewNotNull, - LifeCycle.onViewCreatedNotNull, - LifeCycle.onViewReadyRestore, - LifeCycle.onPoppedOutToFront); - } } diff --git a/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java b/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java index 2090874..9be125c 100644 --- a/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java +++ b/library/android-mvc/src/main/java/com/shipdream/lib/android/mvc/view/MvcActivity.java @@ -355,6 +355,26 @@ private void notifyAllSubMvcFragmentsTheirStateIsManagedByMe(Fragment fragment, } } + /** + * Notify all sub MvcFragments the given fragments they are popping out along with the given holding fragment. + */ + private void notifyAllSubMvcFragmentsTheyArePoppingOut(Fragment fragment, boolean poppingOut) { + if (fragment != null) { + List frags = fragment.getChildFragmentManager().getFragments(); + if (frags != null) { + int size = frags.size(); + for (int i = 0; i < size; i++) { + Fragment frag = frags.get(i); + if (frag != null && frag.isAdded() && frag instanceof MvcFragment) { + ((MvcFragment) frag).isPoppingOut = poppingOut; + } + + notifyAllSubMvcFragmentsTheirStateIsManagedByMe(frag, poppingOut); + } + } + } + } + public void onEvent(final NavigationController.EventC2V.OnLocationForward event) { if (!canCommitFragmentTransaction) { pendingNavActions.add(new Runnable() { @@ -450,10 +470,11 @@ private void performBackNav(NavigationController.EventC2V.OnLocationBack event) final MvcFragment currentFrag = (MvcFragment) fm.findFragmentByTag(currentFragTag); if (currentFrag != null) { currentFrag.injectDependencies(); + currentFrag.isPoppingOut = true; + notifyAllSubMvcFragmentsTheyArePoppingOut(currentFrag, true); currentFrag.registerOnViewReadyListener(new Runnable() { @Override public void run() { - currentFrag.isPoppingOut = true; currentFrag.onPoppedOutToFront(); unregisterOnViewReadyListener(this); } From b256518c6f69983fbb95c68ea23d5cbb0fd7a59a Mon Sep 17 00:00:00 2001 From: Kejun Xia Date: Tue, 18 Aug 2015 22:07:49 +1000 Subject: [PATCH 6/7] Update change log --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index 624694e..cd92dd3 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,6 @@ Version: 1.1.7 Once root fragment is restored, it should notify all nested fragments they are not managed by the root fragment any more +Fix issue that nested fragments of popping out fragment won't call onReturnFromBackground incorrectly Version: 1.1.6 Fix issue that onViewReady is called with incorrect reason - RESTORE which should be FIRST_TIME when the fragment is a page and recreated by FragmentStatePagerAdapter From dc9ed0df625834acf2d9848383902469a9c55349 Mon Sep 17 00:00:00 2001 From: Kejun Xia Date: Tue, 18 Aug 2015 22:13:14 +1000 Subject: [PATCH 7/7] Update maven version for maven repository --- README.md | 4 ++-- documents/sites/Site-MarkDown.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a81ab87..a7702a4 100644 --- a/README.md +++ b/README.md @@ -33,13 +33,13 @@ The library is currently release to jCenter and MavenCentral com.shipdream android-mvc - 1.1.6 + 1.1.7 ``` **Gradle:** ```groovy -compile "com.shipdream:android-mvc:1.1.6" +compile "com.shipdream:android-mvc:1.1.7" ``` ## Dependency injection with reference count diff --git a/documents/sites/Site-MarkDown.md b/documents/sites/Site-MarkDown.md index c5d2acf..34c3017 100644 --- a/documents/sites/Site-MarkDown.md +++ b/documents/sites/Site-MarkDown.md @@ -40,13 +40,13 @@ The library is currently release to jCenter and MavenCentral com.shipdream android-mvc - 1.1.6 + 1.1.7 ``` **Gradle:** ```groovy -compile "com.shipdream:android-mvc:1.1.6" +compile "com.shipdream:android-mvc:1.1.7" ``` ## Samples