[Android] [PATCH] MainActivity, VideoGrid, AudioBrowser, Directories, & History: focus related functional improvements

Mik Amchislavsky hailmikhail at gmail.com
Mon Oct 13 15:31:33 CEST 2014


---
 .../videolan/vlc/gui/DirectoryViewFragment.java    |   19 ++++-
 .../src/org/videolan/vlc/gui/HistoryFragment.java  |   20 ++++-
 .../src/org/videolan/vlc/gui/MainActivity.java     |   83 ++++++++++++++++++++
 .../vlc/gui/audio/AudioBrowserFragment.java        |   34 ++++++--
 .../videolan/vlc/gui/video/VideoGridFragment.java  |   12 ++-
 5 files changed, 159 insertions(+), 9 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java b/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
index 5993bfd..2e366b2 100644
--- a/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
@@ -79,6 +79,14 @@ public class DirectoryViewFragment extends ListFragment implements IRefreshable,
         getActivity().registerReceiver(messageReceiver, filter);
     }
 
+    private void focusHelper(boolean idIsEmpty) {
+        View parent = View.inflate(getActivity(),
+            R.layout.directory_view, null);
+        MainActivity main = (MainActivity)getActivity();
+        main.setMenuFocusDown(idIsEmpty, android.R.id.list);
+        main.setSearchAsFocusDown(idIsEmpty, parent, android.R.id.list);
+    }
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
     {
@@ -87,6 +95,12 @@ public class DirectoryViewFragment extends ListFragment implements IRefreshable,
         View v = inflater.inflate(R.layout.directory_view, container, false);
         setListAdapter(mDirectoryAdapter);
         final ListView listView = (ListView)v.findViewById(android.R.id.list);
+        listView.setNextFocusUpId(R.id.ml_menu_search);
+        listView.setNextFocusLeftId(android.R.id.list);
+        listView.setNextFocusRightId(android.R.id.list);
+        listView.setNextFocusForwardId(android.R.id.list);
+        focusHelper(mDirectoryAdapter.getCount() == 0);
+        listView.requestFocus();
         listView.setOnItemLongClickListener(new OnItemLongClickListener() {
 
             @Override
@@ -204,8 +218,11 @@ public class DirectoryViewFragment extends ListFragment implements IRefreshable,
 
     @Override
     public void refresh() {
-        if (mDirectoryAdapter != null)
+        if (mDirectoryAdapter != null) {
             mDirectoryAdapter.refresh();
+            focusHelper(mDirectoryAdapter.getCount() == 0);
+        } else
+            focusHelper(true);
     }
 
     private final BroadcastReceiver messageReceiver = new BroadcastReceiver() {
diff --git a/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java b/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java
index 42a2219..b32814c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java
@@ -55,6 +55,15 @@ public class HistoryFragment extends ListFragment implements IRefreshable {
         Log.d(TAG, "HistoryFragment()");
     }
 
+    private void focusHelper(boolean idIsEmpty) {
+        View parent = View.inflate(getActivity(), R.layout.history_list,
+            null);
+        MainActivity main = (MainActivity)getActivity();
+        main.setMenuFocusDown(idIsEmpty, android.R.id.list);
+        main.setSearchAsFocusDown(idIsEmpty, parent,
+            android.R.id.list);
+    }
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
     {
@@ -63,6 +72,12 @@ public class HistoryFragment extends ListFragment implements IRefreshable {
         View v = inflater.inflate(R.layout.history_list, container, false);
         setListAdapter(mHistoryAdapter);
         final ListView listView = (ListView)v.findViewById(android.R.id.list);
+        listView.setNextFocusUpId(R.id.ml_menu_search);
+        listView.setNextFocusLeftId(android.R.id.list);
+        listView.setNextFocusRightId(android.R.id.list);
+        listView.setNextFocusForwardId(android.R.id.list);
+        focusHelper(mHistoryAdapter.getCount() == 0);
+        listView.requestFocus();
         registerForContextMenu(listView);
         return v;
     }
@@ -108,7 +123,10 @@ public class HistoryFragment extends ListFragment implements IRefreshable {
     @Override
     public void refresh() {
         Log.d(TAG, "Refreshing view!");
-        if( mHistoryAdapter != null )
+        if( mHistoryAdapter != null ) {
             mHistoryAdapter.refresh();
+            focusHelper(mHistoryAdapter.getCount() == 0);
+        } else
+            focusHelper(true);
     }
 }
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index 7d1321e..d9d8d60 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -134,6 +134,7 @@ public class MainActivity extends ActionBarActivity {
 
     private Handler mHandler = new MainActivityHandler(this);
     private int mFocusedPrior = 0;
+    private int mActionBarIconId = -1;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -695,13 +696,91 @@ public class MainActivity extends ActionBarActivity {
         }
     }
 
+    public void setMenuFocusDown(boolean idIsEmpty, int id) {
+        int[] menu_controls = new int[]{R.id.ml_menu_search,
+            R.id.ml_menu_open_mrl, R.id.ml_menu_sortby,
+            R.id.ml_menu_last_playlist, R.id.ml_menu_refresh,
+            mActionBarIconId};
+		int pane = mSlidingPane.getState();
+        for(int r : menu_controls) {
+            View v = findViewById(r);
+            if (v != null) {
+                if (!idIsEmpty)
+                    v.setNextFocusDownId(id);
+                else {
+                    if (pane ==  mSlidingPane.STATE_CLOSED) {
+                        v.setNextFocusDownId(R.id.play_pause);
+                    } else if (pane == mSlidingPane.STATE_OPENED) {
+                        v.setNextFocusDownId(R.id.header_play_pause);
+                    } else if (pane ==
+                        mSlidingPane.STATE_OPENED_ENTIRELY) {
+                        v.setNextFocusDownId(r);
+                    }
+                }
+            }
+        }
+    }
+
+    public void setSearchAsFocusDown(boolean idIsEmpty, View parentView,
+        int id) {
+        View playPause = findViewById(R.id.header_play_pause);
+        View v_main = LayoutInflater.from(this).inflate(R.layout.main, null);
+
+        if (!idIsEmpty) {
+            View list = null;
+            int pane = mSlidingPane.getState();
+
+            if (parentView == null)
+                list = v_main.findViewById(id);
+            else
+			    list = parentView.findViewById(id);
+
+            if (list != null) {
+                if (pane == mSlidingPane.STATE_OPENED_ENTIRELY) {
+                    list.setNextFocusDownId(id);
+                } else if (pane == mSlidingPane.STATE_OPENED) {
+                    list.setNextFocusDownId(R.id.header_play_pause);
+                    playPause.setNextFocusUpId(id);
+                }
+            }
+        } else {
+           playPause.setNextFocusUpId(R.id.ml_menu_search);
+        }
+    }
+
     // Note. onKeyDown will not occur while moving within a list
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (mFocusedPrior == 0)
+            setMenuFocusDown(true, 0);
         mFocusedPrior = getCurrentFocus().getId();
         return super.onKeyDown(keyCode, event);
     }
 
+    // Note. onKeyDown will not occur while moving within a list
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+		View v = getCurrentFocus();
+        if ((mActionBarIconId == -1) &&
+            (v.getId() == -1)  &&
+            (v.getNextFocusDownId() == -1) &&
+            (v.getNextFocusUpId() == -1) &&
+            (v.getNextFocusLeftId() == -1) &&
+            (v.getNextFocusRightId() == -1) &&
+            (v.getNextFocusForwardId() == -1)) {
+            mActionBarIconId = View.generateViewId();
+            v.setId(mActionBarIconId);
+            v.setNextFocusUpId(mActionBarIconId);
+            v.setNextFocusDownId(mActionBarIconId);
+            v.setNextFocusLeftId(mActionBarIconId);
+            v.setNextFocusRightId(R.id.ml_menu_search);
+            v.setNextFocusForwardId(mActionBarIconId);
+            findViewById(R.id.ml_menu_search).setNextFocusLeftId(
+                mActionBarIconId);
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+
     private void reloadPreferences() {
         SharedPreferences sharedPrefs = getSharedPreferences("MainActivity", MODE_PRIVATE);
         mCurrentFragment = sharedPrefs.getString("fragment", "video");
@@ -846,6 +925,10 @@ public class MainActivity extends ActionBarActivity {
         mAudioPlayerFilling.setVisibility(View.VISIBLE);
     }
 
+    public int  getSlidingPaneState() {
+			return mSlidingPane.getState();
+	}
+
     /**
      * Slide down the audio player.
      * @return true on success else false.
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 ac42f4f..83b31c0 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
@@ -65,7 +65,7 @@ import android.widget.ListView;
 import android.widget.PopupMenu;
 import android.widget.PopupMenu.OnMenuItemClickListener;
 import android.view.KeyEvent;
-
+import android.util.Log;
 public class AudioBrowserFragment extends Fragment {
     public final static String TAG = "VLC/AudioBrowserFragment";
 
@@ -177,6 +177,13 @@ public class AudioBrowserFragment extends Fragment {
         mMediaLibrary.addUpdateHandler(mHandler);
     }
 
+    private void focusHelper(boolean idIsEmpty, int listId) {
+        View parent = getView();
+        MainActivity main = (MainActivity)getActivity();
+        main.setMenuFocusDown(false, R.id.header);
+        main.setSearchAsFocusDown(idIsEmpty, parent, listId);
+    }
+
     // Focus support. Start.
     View.OnKeyListener keyListener = new View.OnKeyListener() {
         @Override
@@ -227,6 +234,10 @@ public class AudioBrowserFragment extends Fragment {
 
                     // assigned in onSwitched following mHeader.scroll
                     mFlingViewPosition = newPosition;
+
+                    ((MainActivity)getActivity()).setSearchAsFocusDown(
+                        vList.getCount() == 0, getView(),
+                        lists[newPosition]);
                 }
             }
 
@@ -442,6 +453,8 @@ public class AudioBrowserFragment extends Fragment {
 
     private void updateLists() {
         List<Media> audioList = MediaLibrary.getInstance().getAudioItems();
+        int listId = MODE_TOTAL;
+		int i;
 
         if (audioList.isEmpty())
             mEmptyView.setVisibility(View.VISIBLE);
@@ -454,39 +467,47 @@ public class AudioBrowserFragment extends Fragment {
         mGenresAdapter.clear();
 
         Collections.sort(audioList, MediaComparators.byName);
-        for (int i = 0; i < audioList.size(); i++) {
+        for (i = 0; i < audioList.size(); i++) {
             Media media = audioList.get(i);
             mSongsAdapter.add(media.getTitle(), media.getArtist(), media);
         }
         mSongsAdapter.addScrollSections();
+        if ((listId == MODE_TOTAL) && (i > 0))
+            listId = MODE_SONG;
 
         Collections.sort(audioList, MediaComparators.byArtist);
-        for (int i = 0; i < audioList.size(); i++) {
+        for (i = 0; i < audioList.size(); i++) {
             Media media = audioList.get(i);
             mArtistsAdapter.add(media.getArtist(), null, media);
         }
         mArtistsAdapter.addLetterSeparators();
+        if (i > 0)
+            listId = MODE_ARTIST;
 
         Collections.sort(audioList, MediaComparators.byAlbum);
-        for (int i = 0; i < audioList.size(); i++) {
+        for (i = 0; i < audioList.size(); i++) {
             Media media = audioList.get(i);
             mAlbumsAdapter.add(media.getAlbum(), media.getArtist(), media);
         }
         mAlbumsAdapter.addLetterSeparators();
+        if ((listId == MODE_TOTAL) && (i > 0))
+            listId = MODE_ALBUM;
 
         Collections.sort(audioList, MediaComparators.byGenre);
-        for (int i = 0; i < audioList.size(); i++) {
+        for (i = 0; i < audioList.size(); i++) {
             Media media = audioList.get(i);
             mGenresAdapter.add(media.getGenre(), null, media);
         }
         mGenresAdapter.addLetterSeparators();
+        if ((listId == MODE_TOTAL) && (i>0))
+            listId = MODE_GENRE;
 
         mSongsAdapter.notifyDataSetChanged();
         mArtistsAdapter.notifyDataSetChanged();
         mAlbumsAdapter.notifyDataSetChanged();
         mGenresAdapter.notifyDataSetChanged();
         // Refresh the fast scroll data, since SectionIndexer doesn't respect notifyDataSetChanged
-        int[] lists = { R.id.songs_list, R.id.artists_list, R.id.albums_list, R.id.genres_list };
+        int[] lists = { R.id.artists_list, R.id.albums_list, R.id.songs_list, R.id.genres_list };
         if(getView() != null) {
             for(int r : lists) {
                 ListView l = (ListView)getView().findViewById(r);
@@ -494,6 +515,7 @@ public class AudioBrowserFragment extends Fragment {
                 l.setFastScrollEnabled(true);
             }
         }
+        focusHelper(listId == MODE_TOTAL, lists[listId]);
     }
 
     AudioBrowserListAdapter.ContextPopupMenuListener mContextPopupMenuListener
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
index 64d7fc1..7f51b08 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
@@ -411,6 +411,14 @@ public class VideoGridFragment extends SherlockGridFragment implements ISortable
         }
     }
 
+    private void focusHelper(boolean idIsEmpty) {
+        View parent = getView();
+		MainActivity main = (MainActivity)getActivity();
+        main.setMenuFocusDown(idIsEmpty, android.R.id.list);
+        main.setSearchAsFocusDown(idIsEmpty, parent,
+            android.R.id.list);
+    }
+
     private void updateList() {
         List<Media> itemList = mMediaLibrary.getVideoItems();
 
@@ -443,7 +451,9 @@ public class VideoGridFragment extends SherlockGridFragment implements ISortable
             mGVFirstVisiblePos = mGridView.getFirstVisiblePosition();
             mGridView.setSelection(mGVFirstVisiblePos);
             mGridView.requestFocus();
-        }
+            focusHelper(false);
+        } else
+            focusHelper(true);
     }
 
     @Override
-- 
1.7.9.5



More information about the Android mailing list