[Android] [PATCH 09/10] Async display for browser fragments

Geoffrey Métais geoffrey.metais at gmail.com
Mon Apr 20 10:49:55 CEST 2015


---
 .../vlc/gui/browser/BaseBrowserAdapter.java        |  16 ++--
 .../vlc/gui/browser/BaseBrowserFragment.java       | 103 ++++++++++++++-------
 .../vlc/gui/browser/FileBrowserFragment.java       |  15 +--
 .../vlc/gui/browser/NetworkBrowserFragment.java    |  30 ++----
 4 files changed, 97 insertions(+), 67 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java
index 79bbd8a..8c348b3 100644
--- a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java
@@ -21,7 +21,6 @@
  */
 package org.videolan.vlc.gui.browser;
 
-import android.os.Parcelable;
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
@@ -155,13 +154,13 @@ public class BaseBrowserAdapter extends  RecyclerView.Adapter<RecyclerView.ViewH
         return mMediaList.isEmpty();
     }
 
-    public void addItem(Media media, boolean root, boolean first){
+    public void addItem(Media media, boolean notify, boolean top){
         MediaWrapper mediaWrapper = new MediaWrapper(media);
-        addItem(mediaWrapper, root, first);
+        addItem(mediaWrapper, notify, top);
 
     }
 
-    public void addItem(Object item, boolean root, boolean top){
+    public void addItem(Object item, boolean notify, boolean top){
         int position = top ? 0 : mMediaList.size();
         if (item instanceof MediaWrapper && ((MediaWrapper)item).getTitle().startsWith("."))
             return;
@@ -169,7 +168,8 @@ public class BaseBrowserAdapter extends  RecyclerView.Adapter<RecyclerView.ViewH
             item = new MediaWrapper((Media) item);
 
         mMediaList.add(position, item);
-        notifyItemInserted(position);
+        if (notify)
+            notifyItemInserted(position);
     }
 
     public void addAll(ArrayList<MediaWrapper> mediaList){
@@ -178,9 +178,11 @@ public class BaseBrowserAdapter extends  RecyclerView.Adapter<RecyclerView.ViewH
             mMediaList.add(mw);
     }
 
-    public void removeItem(int position){
+    public void removeItem(int position, boolean notify){
         mMediaList.remove(position);
-        notifyItemRemoved(position);
+        if (notify) {
+            notifyItemRemoved(position);
+        }
     }
 
     public Object getItem(int position){
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
index 3decbd5..89e036d 100644
--- a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
@@ -66,8 +66,6 @@ import org.videolan.vlc.widget.SwipeRefreshLayout;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
 
 
 public abstract class BaseBrowserFragment extends MediaBrowserFragment implements IRefreshable, MediaBrowser.EventListener, SwipeRefreshLayout.OnRefreshListener {
@@ -76,6 +74,7 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
     public static String ROOT = "smb";
     public static final String KEY_MRL = "key_mrl";
     public static final String KEY_MEDIA = "key_media";
+    public static final String KEY_MEDIA_LIST = "key_media_list";
     public static final String KEY_POSITION = "key_list";
 
     protected BrowserFragmentHandler mHandler;
@@ -90,8 +89,6 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
     protected boolean mRoot;
     protected LibVLC mLibVLC;
 
-    private static final String FILES_LIST = "files_list";
-
     private SparseArray<ArrayList<MediaWrapper>> mMediaLists;
     private ArrayList<MediaWrapper> mediaList;
     public int mCurrentParsedPosition = 0;
@@ -112,7 +109,7 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
         if (bundle == null)
             bundle = getArguments();
         if (bundle != null){
-            mediaList = bundle.getParcelableArrayList(FILES_LIST);
+            mediaList = bundle.getParcelableArrayList(KEY_MEDIA_LIST);
             if (mediaList != null)
                 mAdapter.addAll(mediaList);
             mCurrentMedia = bundle.getParcelable(KEY_MEDIA);
@@ -148,6 +145,8 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
 
     public void onSaveInstanceState(Bundle outState){
         outState.putString(KEY_MRL, mMrl);
+        outState.putParcelable(KEY_MEDIA, mCurrentMedia);
+        outState.putParcelableArrayList(KEY_MEDIA_LIST, mediaList);
         if (mRecyclerView != null) {
             outState.putInt(KEY_POSITION, mLayoutManager.findFirstCompletelyVisibleItemPosition());
         }
@@ -165,6 +164,16 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
             return mCurrentMedia != null ? mCurrentMedia.getTitle() : mMrl;
     }
 
+    @Override
+    protected void display() {
+        if (!mReadyToDisplay) {
+            mReadyToDisplay = true;
+            update();
+            return;
+        }
+        updateDisplay();
+    }
+
     public void goBack(){
         getActivity().getSupportFragmentManager().popBackStack();
     }
@@ -175,7 +184,7 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
         Bundle args = new Bundle();
         ArrayList<MediaWrapper> list = mMediaLists != null ? mMediaLists.get(position) : null;
         if(list != null && !list.isEmpty())
-            args.putParcelableArrayList(FILES_LIST, list);
+            args.putParcelableArrayList(KEY_MEDIA_LIST, list);
         args.putParcelable(KEY_MEDIA, media);
         next.setArguments(args);
         ft.replace(R.id.fragment_placeholder, next, media.getLocation());
@@ -186,27 +195,24 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
 
     @Override
     public void onMediaAdded(int index, Media media) {
-        mAdapter.addItem(media, mRoot, true);
-        updateEmptyView();
+        mAdapter.addItem(media, mReadyToDisplay && mRoot, true);
+        if (mReadyToDisplay)
+            updateEmptyView();
         if (mRoot)
             mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
     }
 
     @Override
     public void onMediaRemoved(int index, Media media) {
-        mAdapter.removeItem(index);
+        mAdapter.removeItem(index, mReadyToDisplay);
     }
 
     @Override
     public void onBrowseEnd() {
-        mAdapter.sortList();
+        mMediaBrowser.release();
         mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
-        if (mSavedPosition > 0) {
-            mLayoutManager.scrollToPositionWithOffset(mSavedPosition, 0);
-            mSavedPosition = 0;
-        }
-        parseSubDirectories();
-        focusHelper(mAdapter.isEmpty());
+        if (mReadyToDisplay)
+            display();
     }
 
     @Override
@@ -231,10 +237,8 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
 
     /**
      * Update views visibility and emptiness info
-     *
-     * @return True if content needs can be refreshed
      */
-    protected boolean updateEmptyView(){
+    protected void updateEmptyView(){
         if (mAdapter.isEmpty()){
             mEmptyView.setText(getString(R.string.directory_empty));
             mEmptyView.setVisibility(View.VISIBLE);
@@ -245,30 +249,42 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
             mRecyclerView.setVisibility(View.VISIBLE);
             mSwipeRefreshLayout.setEnabled(true);
         }
-        return true;
     }
 
-    protected void updateDisplay(){
+    protected void update(){
         if (mMediaBrowser == null)
             mMediaBrowser = new MediaBrowser(mLibVLC, this);
-        if (mAdapter.isEmpty()) {
-            refresh();
-        } else {
-            mAdapter.notifyDataSetChanged();
-            parseSubDirectories();
+        if (mReadyToDisplay) {
+            updateEmptyView();
+            if (mAdapter.isEmpty()) {
+                refresh();
+            } else {
+                updateDisplay();
+            }
         }
     }
 
+    protected void updateDisplay() {
+        if (!mAdapter.isEmpty()) {
+            mAdapter.sortList();
+            if (mSavedPosition > 0) {
+                mLayoutManager.scrollToPositionWithOffset(mSavedPosition, 0);
+                mSavedPosition = 0;
+            }
+        }
+        mAdapter.notifyDataSetChanged();
+        parseSubDirectories();
+        focusHelper(mAdapter.isEmpty());
+    }
+
     @Override
     public void refresh() {
         mAdapter.clear();
-        if (mRoot) {
+        mMediaBrowser.changeEventListener(this);
+        if (mRoot)
             browseRoot();
-            parseSubDirectories();
-        } else {
-            mMediaBrowser.changeEventListener(this);
+        else
             mMediaBrowser.browse(mMrl);
-        }
         mHandler.sendEmptyMessageDelayed(BrowserFragmentHandler.MSG_SHOW_LOADING, 300);
     }
 
@@ -403,12 +419,24 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
     }
 
     protected void parseSubDirectories() {
-        if (mAdapter.isEmpty())
+        if (mCurrentParsedPosition == -1 || mAdapter.isEmpty())
             return;
         mMediaLists = new SparseArray<ArrayList<MediaWrapper>>();
         mMediaBrowser.changeEventListener(mFoldersBrowserListener);
         mCurrentParsedPosition = 0;
-        mMediaBrowser.browse(((MediaWrapper) mAdapter.getItem(0)).getLocation()); //TODO manage non MW
+        Object item;
+        MediaWrapper mw;
+        while (mCurrentParsedPosition <mAdapter.getItemCount()){
+            item = mAdapter.getItem(mCurrentParsedPosition);
+            if (item instanceof MediaWrapper){
+                mw = (MediaWrapper) item;
+                if (mw.getType() == MediaWrapper.TYPE_DIR || mw.getType() == MediaWrapper.TYPE_PLAYLIST){
+                    mMediaBrowser.browse(((MediaWrapper) mAdapter.getItem(mCurrentParsedPosition)).getLocation());
+                    return;
+                }
+            }
+            ++mCurrentParsedPosition;
+        }
     }
 
     private MediaBrowser.EventListener mFoldersBrowserListener = new MediaBrowser.EventListener(){
@@ -429,6 +457,11 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
 
         @Override
         public void onBrowseEnd() {
+            if (mAdapter.isEmpty()) {
+                mCurrentParsedPosition = -1;
+                mMediaBrowser.release();
+                return;
+            }
             String holderText = getDescription(directories.size(), files.size());
             MediaWrapper mw = (MediaWrapper) mAdapter.getItem(mCurrentParsedPosition);
 
@@ -450,8 +483,10 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
                 mMediaBrowser.browse(((MediaWrapper) mAdapter.getItem(mCurrentParsedPosition)).getLocation());
                 directories = new ArrayList<MediaWrapper>();
                 files = new ArrayList<MediaWrapper>();
-            } else
+            } else {
+                mCurrentParsedPosition = -1;
                 mMediaBrowser.release();
+            }
         }
 
         private String getDescription(int folderCount, int mediaFileCount) {
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
index 38b86e2..587cbfb 100644
--- a/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
@@ -93,8 +93,11 @@ public class FileBrowserFragment extends BaseBrowserFragment {
             mAdapter.addItem(mw, false, false);
         }
         mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
-        updateEmptyView();
-        mAdapter.notifyDataSetChanged();
+        if (mReadyToDisplay) {
+            updateEmptyView();
+            mAdapter.notifyDataSetChanged();
+            parseSubDirectories();
+        }
     }
 
     public void onStart(){
@@ -107,8 +110,8 @@ public class FileBrowserFragment extends BaseBrowserFragment {
         filter.addAction(Intent.ACTION_MEDIA_REMOVED);
         filter.addAction(Intent.ACTION_MEDIA_EJECT);
         getActivity().registerReceiver(storageReceiver, filter);
-        if (updateEmptyView())
-            updateDisplay();
+        if (mReadyToDisplay)
+            update();
     }
 
     @Override
@@ -126,8 +129,8 @@ public class FileBrowserFragment extends BaseBrowserFragment {
                     action.equalsIgnoreCase(Intent.ACTION_MEDIA_UNMOUNTED) ||
                     action.equalsIgnoreCase(Intent.ACTION_MEDIA_REMOVED) ||
                     action.equalsIgnoreCase(Intent.ACTION_MEDIA_EJECT)) {
-                if (updateEmptyView())
-                    updateDisplay();
+                if (mReadyToDisplay)
+                    update();
             }
         }
     };
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java
index 45bf69d..e736ebd 100644
--- a/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java
@@ -74,17 +74,11 @@ public class NetworkBrowserFragment extends BaseBrowserFragment {
         getActivity().unregisterReceiver(networkReceiver);
     }
 
-    protected void updateDisplay(){
-        if (mMediaBrowser == null)
-            mMediaBrowser = new MediaBrowser(mLibVLC, this);
-        if (mAdapter.isEmpty())
-            refresh();
-        else if (mRoot)
+    protected void updateDisplay() {
+        if (mRoot)
             updateFavorites();
-        else {
-            mAdapter.notifyDataSetChanged();
-            parseSubDirectories();
-        }
+        mAdapter.notifyDataSetChanged();
+        parseSubDirectories();
     }
 
     @Override
@@ -112,10 +106,10 @@ public class NetworkBrowserFragment extends BaseBrowserFragment {
         if (newSize == 0 && mFavorites == 0)
             return;
         for (int i = 1 ; i <= mFavorites ; ++i){ //remove former favorites
-            mAdapter.removeItem(totalSize-i);
+            mAdapter.removeItem(totalSize-i, mReadyToDisplay);
         }
         if (newSize == 0)
-            mAdapter.removeItem(totalSize-mFavorites-1); //also remove separator if no more fav
+            mAdapter.removeItem(totalSize-mFavorites-1, mReadyToDisplay); //also remove separator if no more fav
         else {
             if (mFavorites == 0)
                 mAdapter.addItem("Network favorites", false, false); //add header if needed
@@ -136,10 +130,8 @@ public class NetworkBrowserFragment extends BaseBrowserFragment {
 
     /**
      * Update views visibility and emptiness info
-     *
-     * @return True if content needs can be refreshed
      */
-    protected boolean updateEmptyView() {
+    protected void updateEmptyView() {
         if (AndroidDevices.hasLANConnection()) {
             if (mAdapter.isEmpty()) {
                 mEmptyView.setText(mRoot ? R.string.network_shares_discovery : R.string.network_empty);
@@ -153,7 +145,6 @@ public class NetworkBrowserFragment extends BaseBrowserFragment {
                     mSwipeRefreshLayout.setEnabled(true);
                 }
             }
-            return true;
         } else {
             if (mEmptyView.getVisibility() == View.GONE) {
                 mEmptyView.setText(R.string.network_connection_needed);
@@ -161,7 +152,6 @@ public class NetworkBrowserFragment extends BaseBrowserFragment {
                 mRecyclerView.setVisibility(View.GONE);
                 mSwipeRefreshLayout.setEnabled(false);
             }
-            return false;
         }
     }
 
@@ -169,9 +159,9 @@ public class NetworkBrowserFragment extends BaseBrowserFragment {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action))
-                if (updateEmptyView())
-                    updateDisplay();
+            if (mReadyToDisplay && ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
+                update();
+            }
         }
     };
 }
-- 
2.1.0



More information about the Android mailing list