[Android] MainActivity: fix and document onResumeFragments() behaviour
Edward Wang
git at videolan.org
Sun Mar 3 23:15:52 CET 2013
vlc-ports/android | branch: master | Edward Wang <edward.c.wang at compdigitec.com> | Sun Mar 3 16:14:58 2013 -0500| [0aa11efe1e8b13291209ac5afd860980772def13] | committer: Edward Wang
MainActivity: fix and document onResumeFragments() behaviour
This should fix a lot of fragment and fragment lifecycle related bugs.
> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=0aa11efe1e8b13291209ac5afd860980772def13
---
.../src/org/videolan/vlc/gui/MainActivity.java | 44 ++++++++++++++++----
.../src/org/videolan/vlc/gui/SidebarAdapter.java | 19 +++++++++
2 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index b0e56b4..142249c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -51,7 +51,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.Display;
@@ -311,13 +310,11 @@ public class MainActivity extends SherlockFragmentActivity {
MediaLibrary.getInstance(this).loadMediaItems(this);
}
-
-
@Override
protected void onResumeFragments() {
super.onResumeFragments();
- /* Restore last view */
+ // Figure out if currently-loaded fragment is a top-level fragment.
Fragment current = getSupportFragmentManager()
.findFragmentById(R.id.fragment_placeholder);
boolean found = false;
@@ -331,13 +328,42 @@ public class MainActivity extends SherlockFragmentActivity {
} else {
found = true;
}
- /* Don't call replace() on a non-sidebar fragment, since replace() will
- * remove() the currently displayed fragment and replace it with a
- * blank screen.
+
+ mSidebarAdapter.lockSemaphore();
+ /**
+ * Let's see if Android recreated anything for us in the bundle.
+ * Prevent duplicate creation of fragments, since mSidebarAdapter might
+ * have been purged (losing state) when this activity was killed.
+ */
+ for(int i = 0; i < SidebarAdapter.entries.size(); i++) {
+ String fragmentTag = SidebarAdapter.entries.get(i).id;
+ Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
+ if(fragment != null) {
+ Log.d(TAG, "Restoring automatically recreated fragment \"" + fragmentTag + "\"");
+ mSidebarAdapter.restoreFragment(fragmentTag, fragment);
+ }
+ }
+ mSidebarAdapter.unlockSemaphore();
+
+ /**
+ * Restore the last view.
+ *
+ * Replace:
+ * - null fragments (freshly opened Activity)
+ * - Wrong fragment open AND currently displayed fragment is a top-level fragment
+ *
+ * Do not replace:
+ * - Non-sidebar fragments.
+ * It will try to remove() the currently displayed fragment
+ * (i.e. tracks) and replace it with a blank screen. (stuck menu bug)
*/
- if(found) {
+ if(current == null || (!current.getTag().equals(mCurrentFragment) && found)) {
+ Log.d(TAG, "Reloading displayed fragment");
+ Fragment ff = getFragment(mCurrentFragment);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- ft.replace(R.id.fragment_placeholder, getFragment(mCurrentFragment));
+ if(current != null)
+ ft.detach(current);
+ ft.attach(ff);
ft.commit();
}
}
diff --git a/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java b/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
index b616f3f..05ed1f9 100644
--- a/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
@@ -33,6 +33,7 @@ import org.videolan.vlc.gui.video.VideoGridFragment;
import android.graphics.drawable.Drawable;
import android.support.v4.app.Fragment;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -176,4 +177,22 @@ public class SidebarAdapter extends BaseAdapter {
public void unlockSemaphore() {
mSemaphore.release();
}
+
+ /**
+ * When Android has automatically recreated a fragment from the bundle state,
+ * use this function to 'restore' the recreated fragment into this sidebar
+ * adapter to prevent it from trying to create the same fragment again.
+ *
+ * @param id ID of the fragment
+ * @param f The fragment itself
+ */
+ public void restoreFragment(String id, Fragment f) {
+ if(f == null) {
+ Log.e(TAG, "Can't set null fragment for " + id + "!");
+ return;
+ }
+ mFragments.put(id, f);
+ mFragmentAdded.put(id, true);
+ // if Android added it, it's been implicitly added already...
+ }
}
More information about the Android
mailing list