[Android] Use user visibility hints to prevent duplicate context menu events

Edward Wang git at videolan.org
Sun Mar 3 23:15:51 CET 2013


vlc-ports/android | branch: master | Edward Wang <edward.c.wang at compdigitec.com> | Sat Mar  2 17:52:23 2013 -0500| [b3c7c84d2b5dc998dc2bc00daa2dc5f5fdbf7b93] | committer: Edward Wang

Use user visibility hints to prevent duplicate context menu events

Notably, this fixes the bug where a song randomly plays when trying to delete a file.

http://stackoverflow.com/questions/5297842/how-to-handle-oncontextitemselected-in-a-multi-fragment-activity

> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=b3c7c84d2b5dc998dc2bc00daa2dc5f5fdbf7b93
---

 .../videolan/vlc/gui/DirectoryViewFragment.java    |    2 ++
 .../src/org/videolan/vlc/gui/MainActivity.java     |   24 +++++++++++++++++++-
 .../vlc/gui/audio/AudioBrowserFragment.java        |    2 ++
 .../videolan/vlc/gui/audio/AudioListFragment.java  |    2 ++
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java b/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
index 8b63020..fdfb23e 100644
--- a/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
@@ -114,6 +114,8 @@ public class DirectoryViewFragment extends SherlockListFragment implements ISort
 
     @Override
     public boolean onContextItemSelected(MenuItem item) {
+        if(!getUserVisibleHint()) return super.onContextItemSelected(item);
+
         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
         if(info == null) // info can be null
             return super.onContextItemSelected(item);
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index d018fb0..b0e56b4 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -51,6 +51,7 @@ 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;
@@ -200,7 +201,7 @@ public class MainActivity extends SherlockFragmentActivity {
                 SidebarAdapter.SidebarEntry entry = (SidebarEntry) listView.getItemAtPosition(position);
                 Fragment current = getSupportFragmentManager().findFragmentById(R.id.fragment_placeholder);
 
-                if(current == null || current.getTag() == entry.id) { /* Already selected */
+                if(current == null || current.getTag().equals(entry.id)) { /* Already selected */
                     mMenu.showContent();
                     return;
                 }
@@ -214,11 +215,32 @@ public class MainActivity extends SherlockFragmentActivity {
                     getSupportFragmentManager().popBackStack();
                 }
 
+                /**
+                 * Do not move this getFragment("audio")!
+                 * This is to ensure that if audio is not already loaded, it
+                 * will be loaded ahead of the detach/attach below.
+                 * Otherwise if you add() a fragment after an attach/detach,
+                 * it will take over the placeholder and you will end up with
+                 * the audio fragment when some other fragment should be there.
+                 */
+                Fragment audioFragment = getFragment("audio");
+
                 FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                 ft.detach(current);
                 ft.attach(getFragment(entry.id));
                 ft.commit();
                 mCurrentFragment = entry.id;
+
+                /*
+                 * Set user visibility hints to work around weird Android
+                 * behaviour of duplicate context menu events.
+                 */
+                current.setUserVisibleHint(false);
+                getFragment(mCurrentFragment).setUserVisibleHint(true);
+                // HACK ALERT: Set underlying audio browser to be invisible too.
+                if(current.getTag().equals("tracks"))
+                    audioFragment.setUserVisibleHint(false);
+
                 mMenu.showContent();
             }
         });
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
index 7f0720f..c0e5f5d 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
@@ -254,6 +254,8 @@ public class AudioBrowserFragment extends SherlockFragment implements ISortable
 
     @Override
     public boolean onContextItemSelected(MenuItem item) {
+        if(!getUserVisibleHint()) return super.onContextItemSelected(item);
+
         ContextMenuInfo menuInfo = item.getMenuInfo();
         if(menuInfo == null) return super.onContextItemSelected(item);
 
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioListFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioListFragment.java
index e118370..8122e94 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioListFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioListFragment.java
@@ -138,6 +138,8 @@ public class AudioListFragment extends SherlockListFragment {
 
     @Override
     public boolean onContextItemSelected(MenuItem item) {
+        if(!getUserVisibleHint()) return super.onContextItemSelected(item);
+
         AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
         if(menuInfo == null) // getMenuInfo can be NULL
             return super.onContextItemSelected(item);



More information about the Android mailing list