The LibraryFragments are now loading their content async.

This commit is contained in:
Karim Abou Zeid 2016-03-20 21:11:21 +01:00
commit 4e6df0faf8
15 changed files with 367 additions and 54 deletions

View file

@ -45,16 +45,12 @@ public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewH
protected final AppCompatActivity activity; protected final AppCompatActivity activity;
protected ArrayList<Playlist> dataSet; protected ArrayList<Playlist> dataSet;
protected int itemLayoutRes; protected int itemLayoutRes;
protected int favoritePlaylistId;
public PlaylistAdapter(AppCompatActivity activity, ArrayList<Playlist> dataSet, @LayoutRes int itemLayoutRes, @Nullable CabHolder cabHolder) { public PlaylistAdapter(AppCompatActivity activity, ArrayList<Playlist> dataSet, @LayoutRes int itemLayoutRes, @Nullable CabHolder cabHolder) {
super(activity, cabHolder, R.menu.menu_playlists_selection); super(activity, cabHolder, R.menu.menu_playlists_selection);
this.activity = activity; this.activity = activity;
this.dataSet = dataSet; this.dataSet = dataSet;
this.itemLayoutRes = itemLayoutRes; this.itemLayoutRes = itemLayoutRes;
favoritePlaylistId = MusicUtil.getFavoritesPlaylist(activity).id;
setHasStableIds(true); setHasStableIds(true);
} }
@ -64,7 +60,6 @@ public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewH
public void swapDataSet(ArrayList<Playlist> dataSet) { public void swapDataSet(ArrayList<Playlist> dataSet) {
this.dataSet = dataSet; this.dataSet = dataSet;
favoritePlaylistId = MusicUtil.getFavoritesPlaylist(activity).id;
notifyDataSetChanged(); notifyDataSetChanged();
} }
@ -113,7 +108,7 @@ public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewH
if (playlist instanceof AbsSmartPlaylist) { if (playlist instanceof AbsSmartPlaylist) {
return ((AbsSmartPlaylist) playlist).iconRes; return ((AbsSmartPlaylist) playlist).iconRes;
} }
return playlist.id == favoritePlaylistId ? R.drawable.ic_favorite_white_24dp : R.drawable.ic_queue_music_white_24dp; return MusicUtil.isFavoritePlaylist(activity, playlist) ? R.drawable.ic_favorite_white_24dp : R.drawable.ic_queue_music_white_24dp;
} }
@Override @Override

View file

@ -40,7 +40,7 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
public static final String TAG = AlbumAdapter.class.getSimpleName(); public static final String TAG = AlbumAdapter.class.getSimpleName();
protected final AppCompatActivity activity; protected final AppCompatActivity activity;
protected List<Album> dataSet; protected ArrayList<Album> dataSet;
protected int itemLayoutRes; protected int itemLayoutRes;
@ -61,11 +61,15 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void swapDataSet(List<Album> dataSet) { public void swapDataSet(ArrayList<Album> dataSet) {
this.dataSet = dataSet; this.dataSet = dataSet;
notifyDataSetChanged(); notifyDataSetChanged();
} }
public ArrayList<Album> getDataSet() {
return dataSet;
}
@NonNull @NonNull
@Override @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View file

@ -65,6 +65,10 @@ public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolde
notifyDataSetChanged(); notifyDataSetChanged();
} }
public ArrayList<Artist> getDataSet() {
return dataSet;
}
public void usePalette(boolean usePalette) { public void usePalette(boolean usePalette) {
this.usePalette = usePalette; this.usePalette = usePalette;
notifyDataSetChanged(); notifyDataSetChanged();

View file

@ -11,12 +11,11 @@ import android.support.annotation.Nullable;
import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Playlist;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class PlaylistLoader { public class PlaylistLoader {
@NonNull @NonNull
public static List<Playlist> getAllPlaylists(@NonNull final Context context) { public static ArrayList<Playlist> getAllPlaylists(@NonNull final Context context) {
return getAllPlaylists(makePlaylistCursor(context, null, null)); return getAllPlaylists(makePlaylistCursor(context, null, null));
} }
@ -55,8 +54,8 @@ public class PlaylistLoader {
} }
@NonNull @NonNull
public static List<Playlist> getAllPlaylists(@Nullable final Cursor cursor) { public static ArrayList<Playlist> getAllPlaylists(@Nullable final Cursor cursor) {
List<Playlist> playlists = new ArrayList<>(); ArrayList<Playlist> playlists = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) { if (cursor != null && cursor.moveToFirst()) {
do { do {

View file

@ -0,0 +1,76 @@
package com.kabouzeid.gramophone.misc;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
import hugo.weaving.DebugLog;
/**
* <a href="http://code.google.com/p/android/issues/detail?id=14944">Issue
* 14944</a>
*
* @author Alexander Blom
*/
public abstract class WrappedAsyncTaskLoader<D> extends AsyncTaskLoader<D> {
private D mData;
/**
* Constructor of <code>WrappedAsyncTaskLoader</code>
*
* @param context The {@link Context} to use.
*/
public WrappedAsyncTaskLoader(Context context) {
super(context);
}
/**
* {@inheritDoc}
*/
@DebugLog
@Override
public void deliverResult(D data) {
if (!isReset()) {
this.mData = data;
super.deliverResult(data);
} else {
// An asynchronous query came in while the loader is stopped
}
}
/**
* {@inheritDoc}
*/
@DebugLog
@Override
protected void onStartLoading() {
if (this.mData != null) {
deliverResult(this.mData);
} else if (takeContentChanged() || this.mData == null) {
forceLoad();
}
}
/**
* {@inheritDoc}
*/
@DebugLog
@Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible
cancelLoad();
}
/**
* {@inheritDoc}
*/
@DebugLog
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
this.mData = null;
}
}

View file

@ -355,7 +355,8 @@ public class MultiPlayer implements Playback, MediaPlayer.OnErrorListener, Media
// SystemClock.sleep(25); // SystemClock.sleep(25);
mNextPlayer.start(); mNextPlayer.start();
} }
mCompletion.onCompletion(this); if (mCompletion != null)
mCompletion.onCompletion(this);
} }
} }
} }

View file

@ -2,6 +2,7 @@ package com.kabouzeid.gramophone.ui.fragments.libraryfragments;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import com.kabouzeid.gramophone.ui.fragments.LibraryFragment; import com.kabouzeid.gramophone.ui.fragments.LibraryFragment;
@ -10,6 +11,12 @@ import com.kabouzeid.gramophone.ui.fragments.LibraryFragment;
*/ */
public class AbsLibraryPagerFragment extends Fragment { public class AbsLibraryPagerFragment extends Fragment {
/* http://stackoverflow.com/a/2888433 */
@Override
public LoaderManager getLoaderManager() {
return getParentFragment().getLoaderManager();
}
public LibraryFragment getLibraryFragment() { public LibraryFragment getLibraryFragment() {
return (LibraryFragment) getParentFragment(); return (LibraryFragment) getParentFragment();
} }

View file

@ -1,7 +1,10 @@
package com.kabouzeid.gramophone.ui.fragments.libraryfragments; package com.kabouzeid.gramophone.ui.fragments.libraryfragments;
import android.os.Bundle;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.util.Util; import com.kabouzeid.gramophone.util.Util;
@ -14,6 +17,7 @@ public abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A extend
private boolean usePaletteInitialized; private boolean usePaletteInitialized;
private boolean usePalette; private boolean usePalette;
private int currentLayoutRes;
public final int getGridSize() { public final int getGridSize() {
if (gridSize == 0) { if (gridSize == 0) {
@ -53,7 +57,7 @@ public abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A extend
} else { } else {
saveGridSize(gridSize); saveGridSize(gridSize);
} }
// only recreate the adapter and layout manager if the layout res has changed // only recreate the adapter and layout manager if the layout currentLayoutRes has changed
if (oldLayoutRes != getItemLayoutRes()) { if (oldLayoutRes != getItemLayoutRes()) {
invalidateLayoutManager(); invalidateLayoutManager();
invalidateAdapter(); invalidateAdapter();
@ -76,7 +80,7 @@ public abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A extend
} }
/** /**
* Override to customize which item layout res should be used. You might also want to override {@link #canUsePalette()} then. * Override to customize which item layout currentLayoutRes should be used. You might also want to override {@link #canUsePalette()} then.
* *
* @see #getGridSize() * @see #getGridSize()
*/ */
@ -88,14 +92,28 @@ public abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A extend
return R.layout.item_list; return R.layout.item_list;
} }
protected void applyRecyclerViewPaddingForLayoutRes(@LayoutRes int res) { protected final void notifyLayoutResChanged(@LayoutRes int res) {
this.currentLayoutRes = res;
RecyclerView recyclerView = getRecyclerView();
if (recyclerView != null) {
applyRecyclerViewPaddingForLayoutRes(recyclerView, currentLayoutRes);
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
applyRecyclerViewPaddingForLayoutRes(getRecyclerView(), currentLayoutRes);
}
protected void applyRecyclerViewPaddingForLayoutRes(@NonNull RecyclerView recyclerView, @LayoutRes int res) {
int padding; int padding;
if (res == R.layout.item_grid) { if (res == R.layout.item_grid) {
padding = (int) (getResources().getDisplayMetrics().density * 2); padding = (int) (getResources().getDisplayMetrics().density * 2);
} else { } else {
padding = 0; padding = 0;
} }
getRecyclerView().setPadding(padding, padding, padding, padding); recyclerView.setPadding(padding, padding, padding, padding);
} }
protected abstract int loadGridSize(); protected abstract int loadGridSize();

View file

@ -40,6 +40,13 @@ public abstract class AbsLibraryPagerRecyclerViewFragment<A extends RecyclerView
private A adapter; private A adapter;
private LM layoutManager; private LM layoutManager;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initLayoutManager();
initAdapter(); // makes sure the adapter is not null when the loader finishes loading
}
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(getLayoutRes(), container, false); View view = inflater.inflate(getLayoutRes(), container, false);
@ -55,19 +62,27 @@ public abstract class AbsLibraryPagerRecyclerViewFragment<A extends RecyclerView
getLibraryFragment().getMainActivity().addMusicServiceEventListener(this); getLibraryFragment().getMainActivity().addMusicServiceEventListener(this);
setUpRecyclerView(); setUpRecyclerView();
checkIsEmpty();
} }
private void setUpRecyclerView() { private void setUpRecyclerView() {
if (recyclerView instanceof FastScrollRecyclerView) { if (recyclerView instanceof FastScrollRecyclerView) {
ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(), ((FastScrollRecyclerView) recyclerView), ThemeStore.accentColor(getActivity())); ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(), ((FastScrollRecyclerView) recyclerView), ThemeStore.accentColor(getActivity()));
} }
invalidateLayoutManager(); recyclerView.setLayoutManager(layoutManager);
invalidateAdapter(); recyclerView.setAdapter(adapter);
}
protected void invalidateLayoutManager() {
initLayoutManager();
recyclerView.setLayoutManager(layoutManager);
} }
protected void invalidateAdapter() { protected void invalidateAdapter() {
initAdapter();
recyclerView.setAdapter(adapter);
}
private void initAdapter() {
adapter = createAdapter(); adapter = createAdapter();
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override @Override
@ -76,12 +91,11 @@ public abstract class AbsLibraryPagerRecyclerViewFragment<A extends RecyclerView
checkIsEmpty(); checkIsEmpty();
} }
}); });
recyclerView.setAdapter(adapter); checkIsEmpty();
} }
protected void invalidateLayoutManager() { private void initLayoutManager() {
layoutManager = createLayoutManager(); layoutManager = createLayoutManager();
recyclerView.setLayoutManager(layoutManager);
} }
protected A getAdapter() { protected A getAdapter() {
@ -128,11 +142,8 @@ public abstract class AbsLibraryPagerRecyclerViewFragment<A extends RecyclerView
private void checkIsEmpty() { private void checkIsEmpty() {
if (empty != null) { if (empty != null) {
RecyclerView.Adapter adapter = getAdapter(); empty.setText(getEmptyMessage());
if (adapter != null) { empty.setVisibility(adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
empty.setText(getEmptyMessage());
empty.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
} }
} }
@ -148,6 +159,7 @@ public abstract class AbsLibraryPagerRecyclerViewFragment<A extends RecyclerView
protected abstract LM createLayoutManager(); protected abstract LM createLayoutManager();
@NonNull
protected abstract A createAdapter(); protected abstract A createAdapter();
@Override @Override

View file

@ -1,19 +1,38 @@
package com.kabouzeid.gramophone.ui.fragments.libraryfragments; package com.kabouzeid.gramophone.ui.fragments.libraryfragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.MusicLibraryPagerAdapter;
import com.kabouzeid.gramophone.adapter.album.AlbumAdapter; import com.kabouzeid.gramophone.adapter.album.AlbumAdapter;
import com.kabouzeid.gramophone.loader.AlbumLoader; import com.kabouzeid.gramophone.loader.AlbumLoader;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.util.PreferenceUtil; import com.kabouzeid.gramophone.util.PreferenceUtil;
import java.util.ArrayList;
import hugo.weaving.DebugLog;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager> { public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager> implements LoaderManager.LoaderCallbacks<ArrayList<Album>> {
public static final String TAG = AlbumsFragment.class.getSimpleName(); public static final String TAG = AlbumsFragment.class.getSimpleName();
private static final int LOADER_ID = MusicLibraryPagerAdapter.MusicFragments.ALBUM.ordinal();
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
@Override @Override
protected GridLayoutManager createLayoutManager() { protected GridLayoutManager createLayoutManager() {
return new GridLayoutManager(getActivity(), getGridSize()); return new GridLayoutManager(getActivity(), getGridSize());
@ -23,10 +42,11 @@ public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFra
@Override @Override
protected AlbumAdapter createAdapter() { protected AlbumAdapter createAdapter() {
int itemLayoutRes = getItemLayoutRes(); int itemLayoutRes = getItemLayoutRes();
applyRecyclerViewPaddingForLayoutRes(itemLayoutRes); notifyLayoutResChanged(itemLayoutRes);
ArrayList<Album> dataSet = getAdapter() == null ? new ArrayList<Album>() : getAdapter().getDataSet();
return new AlbumAdapter( return new AlbumAdapter(
getLibraryFragment().getMainActivity(), getLibraryFragment().getMainActivity(),
AlbumLoader.getAllAlbums(getActivity()), dataSet,
itemLayoutRes, itemLayoutRes,
loadUsePalette(), loadUsePalette(),
getLibraryFragment()); getLibraryFragment());
@ -80,6 +100,36 @@ public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFra
@Override @Override
public void onMediaStoreChanged() { public void onMediaStoreChanged() {
getAdapter().swapDataSet(AlbumLoader.getAllAlbums(getActivity())); getLoaderManager().restartLoader(LOADER_ID, null, this);
}
@DebugLog
@Override
public Loader<ArrayList<Album>> onCreateLoader(int id, Bundle args) {
return new AsyncAlbumLoader(getActivity());
}
@DebugLog
@Override
public void onLoadFinished(Loader<ArrayList<Album>> loader, ArrayList<Album> data) {
getAdapter().swapDataSet(data);
}
@DebugLog
@Override
public void onLoaderReset(Loader<ArrayList<Album>> loader) {
getAdapter().swapDataSet(new ArrayList<Album>());
}
private static class AsyncAlbumLoader extends WrappedAsyncTaskLoader<ArrayList<Album>> {
public AsyncAlbumLoader(Context context) {
super(context);
}
@DebugLog
@Override
public ArrayList<Album> loadInBackground() {
return AlbumLoader.getAllAlbums(getContext());
}
} }
} }

View file

@ -1,20 +1,39 @@
package com.kabouzeid.gramophone.ui.fragments.libraryfragments; package com.kabouzeid.gramophone.ui.fragments.libraryfragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.MusicLibraryPagerAdapter;
import com.kabouzeid.gramophone.adapter.artist.ArtistAdapter; import com.kabouzeid.gramophone.adapter.artist.ArtistAdapter;
import com.kabouzeid.gramophone.loader.ArtistLoader; import com.kabouzeid.gramophone.loader.ArtistLoader;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.util.PreferenceUtil; import com.kabouzeid.gramophone.util.PreferenceUtil;
import java.util.ArrayList;
import hugo.weaving.DebugLog;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager> { public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager> implements LoaderManager.LoaderCallbacks<ArrayList<Artist>> {
public static final String TAG = ArtistsFragment.class.getSimpleName(); public static final String TAG = ArtistsFragment.class.getSimpleName();
private static final int LOADER_ID = MusicLibraryPagerAdapter.MusicFragments.ARTIST.ordinal();
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
@NonNull @NonNull
@Override @Override
protected GridLayoutManager createLayoutManager() { protected GridLayoutManager createLayoutManager() {
@ -25,10 +44,11 @@ public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFr
@Override @Override
protected ArtistAdapter createAdapter() { protected ArtistAdapter createAdapter() {
int itemLayoutRes = getItemLayoutRes(); int itemLayoutRes = getItemLayoutRes();
applyRecyclerViewPaddingForLayoutRes(itemLayoutRes); notifyLayoutResChanged(itemLayoutRes);
ArrayList<Artist> dataSet = getAdapter() == null ? new ArrayList<Artist>() : getAdapter().getDataSet();
return new ArtistAdapter( return new ArtistAdapter(
getLibraryFragment().getMainActivity(), getLibraryFragment().getMainActivity(),
ArtistLoader.getAllArtists(getActivity()), dataSet,
itemLayoutRes, itemLayoutRes,
loadUsePalette(), loadUsePalette(),
getLibraryFragment()); getLibraryFragment());
@ -41,7 +61,7 @@ public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFr
@Override @Override
public void onMediaStoreChanged() { public void onMediaStoreChanged() {
getAdapter().swapDataSet(ArtistLoader.getAllArtists(getActivity())); getLoaderManager().restartLoader(LOADER_ID, null, this);
} }
@Override @Override
@ -84,4 +104,34 @@ public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFr
getLayoutManager().setSpanCount(gridSize); getLayoutManager().setSpanCount(gridSize);
getAdapter().notifyDataSetChanged(); getAdapter().notifyDataSetChanged();
} }
@DebugLog
@Override
public Loader<ArrayList<Artist>> onCreateLoader(int id, Bundle args) {
return new AsyncArtistLoader(getActivity());
}
@DebugLog
@Override
public void onLoadFinished(Loader<ArrayList<Artist>> loader, ArrayList<Artist> data) {
getAdapter().swapDataSet(data);
}
@DebugLog
@Override
public void onLoaderReset(Loader<ArrayList<Artist>> loader) {
getAdapter().swapDataSet(new ArrayList<Artist>());
}
private static class AsyncArtistLoader extends WrappedAsyncTaskLoader<ArrayList<Artist>> {
public AsyncArtistLoader(Context context) {
super(context);
}
@DebugLog
@Override
public ArrayList<Artist> loadInBackground() {
return ArtistLoader.getAllArtists(getContext());
}
}
} }

View file

@ -1,11 +1,17 @@
package com.kabouzeid.gramophone.ui.fragments.libraryfragments; package com.kabouzeid.gramophone.ui.fragments.libraryfragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.MusicLibraryPagerAdapter;
import com.kabouzeid.gramophone.adapter.PlaylistAdapter; import com.kabouzeid.gramophone.adapter.PlaylistAdapter;
import com.kabouzeid.gramophone.loader.PlaylistLoader; import com.kabouzeid.gramophone.loader.PlaylistLoader;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.model.smartplaylist.HistoryPlaylist; import com.kabouzeid.gramophone.model.smartplaylist.HistoryPlaylist;
import com.kabouzeid.gramophone.model.smartplaylist.LastAddedPlaylist; import com.kabouzeid.gramophone.model.smartplaylist.LastAddedPlaylist;
@ -13,13 +19,23 @@ import com.kabouzeid.gramophone.model.smartplaylist.MyTopTracksPlaylist;
import java.util.ArrayList; import java.util.ArrayList;
import hugo.weaving.DebugLog;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public class PlaylistsFragment extends AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, LinearLayoutManager> { public class PlaylistsFragment extends AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, LinearLayoutManager> implements LoaderManager.LoaderCallbacks<ArrayList<Playlist>> {
public static final String TAG = PlaylistsFragment.class.getSimpleName(); public static final String TAG = PlaylistsFragment.class.getSimpleName();
private static final int LOADER_ID = MusicLibraryPagerAdapter.MusicFragments.PLAYLIST.ordinal();
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
@NonNull @NonNull
@Override @Override
protected LinearLayoutManager createLayoutManager() { protected LinearLayoutManager createLayoutManager() {
@ -29,7 +45,8 @@ public class PlaylistsFragment extends AbsLibraryPagerRecyclerViewFragment<Playl
@NonNull @NonNull
@Override @Override
protected PlaylistAdapter createAdapter() { protected PlaylistAdapter createAdapter() {
return new PlaylistAdapter(getLibraryFragment().getMainActivity(), getAllPlaylists(), R.layout.item_list_single_row, getLibraryFragment()); ArrayList<Playlist> dataSet = getAdapter() == null ? new ArrayList<Playlist>() : getAdapter().getDataSet();
return new PlaylistAdapter(getLibraryFragment().getMainActivity(), dataSet, R.layout.item_list_single_row, getLibraryFragment());
} }
@Override @Override
@ -39,18 +56,48 @@ public class PlaylistsFragment extends AbsLibraryPagerRecyclerViewFragment<Playl
@Override @Override
public void onMediaStoreChanged() { public void onMediaStoreChanged() {
getAdapter().swapDataSet(getAllPlaylists()); getLoaderManager().restartLoader(LOADER_ID, null, this);
} }
private ArrayList<Playlist> getAllPlaylists() { @DebugLog
ArrayList<Playlist> playlists = new ArrayList<>(); @Override
public Loader<ArrayList<Playlist>> onCreateLoader(int id, Bundle args) {
return new AsyncPlaylistLoader(getActivity());
}
playlists.add(new LastAddedPlaylist(getActivity())); @DebugLog
playlists.add(new HistoryPlaylist(getActivity())); @Override
playlists.add(new MyTopTracksPlaylist(getActivity())); public void onLoadFinished(Loader<ArrayList<Playlist>> loader, ArrayList<Playlist> data) {
getAdapter().swapDataSet(data);
}
playlists.addAll(PlaylistLoader.getAllPlaylists(getActivity())); @DebugLog
@Override
public void onLoaderReset(Loader<ArrayList<Playlist>> loader) {
getAdapter().swapDataSet(new ArrayList<Playlist>());
}
return playlists; private static class AsyncPlaylistLoader extends WrappedAsyncTaskLoader<ArrayList<Playlist>> {
public AsyncPlaylistLoader(Context context) {
super(context);
}
private static ArrayList<Playlist> getAllPlaylists(Context context) {
ArrayList<Playlist> playlists = new ArrayList<>();
playlists.add(new LastAddedPlaylist(context));
playlists.add(new HistoryPlaylist(context));
playlists.add(new MyTopTracksPlaylist(context));
playlists.addAll(PlaylistLoader.getAllPlaylists(context));
return playlists;
}
@DebugLog
@Override
public ArrayList<Playlist> loadInBackground() {
return getAllPlaylists(getContext());
}
} }
} }

View file

@ -1,24 +1,40 @@
package com.kabouzeid.gramophone.ui.fragments.libraryfragments; package com.kabouzeid.gramophone.ui.fragments.libraryfragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.MusicLibraryPagerAdapter;
import com.kabouzeid.gramophone.adapter.song.ShuffleButtonSongAdapter; import com.kabouzeid.gramophone.adapter.song.ShuffleButtonSongAdapter;
import com.kabouzeid.gramophone.adapter.song.SongAdapter; import com.kabouzeid.gramophone.adapter.song.SongAdapter;
import com.kabouzeid.gramophone.loader.SongLoader; import com.kabouzeid.gramophone.loader.SongLoader;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.PreferenceUtil; import com.kabouzeid.gramophone.util.PreferenceUtil;
import java.util.ArrayList; import java.util.ArrayList;
import hugo.weaving.DebugLog;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public class SongsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager> { public class SongsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager> implements LoaderManager.LoaderCallbacks<ArrayList<Song>> {
public static final String TAG = SongsFragment.class.getSimpleName(); public static final String TAG = SongsFragment.class.getSimpleName();
private static final int LOADER_ID = MusicLibraryPagerAdapter.MusicFragments.SONG.ordinal();
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
@NonNull @NonNull
@Override @Override
protected GridLayoutManager createLayoutManager() { protected GridLayoutManager createLayoutManager() {
@ -28,22 +44,22 @@ public class SongsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFrag
@NonNull @NonNull
@Override @Override
protected SongAdapter createAdapter() { protected SongAdapter createAdapter() {
ArrayList<Song> songs = SongLoader.getAllSongs(getActivity());
int itemLayoutRes = getItemLayoutRes(); int itemLayoutRes = getItemLayoutRes();
applyRecyclerViewPaddingForLayoutRes(itemLayoutRes); notifyLayoutResChanged(itemLayoutRes);
boolean usePalette = loadUsePalette(); boolean usePalette = loadUsePalette();
ArrayList<Song> dataSet = getAdapter() == null ? new ArrayList<Song>() : getAdapter().getDataSet();
if (getGridSize() <= getMaxGridSizeForList()) { if (getGridSize() <= getMaxGridSizeForList()) {
return new ShuffleButtonSongAdapter( return new ShuffleButtonSongAdapter(
getLibraryFragment().getMainActivity(), getLibraryFragment().getMainActivity(),
songs, dataSet,
itemLayoutRes, itemLayoutRes,
usePalette, usePalette,
getLibraryFragment()); getLibraryFragment());
} }
return new SongAdapter( return new SongAdapter(
getLibraryFragment().getMainActivity(), getLibraryFragment().getMainActivity(),
songs, dataSet,
itemLayoutRes, itemLayoutRes,
usePalette, usePalette,
getLibraryFragment()); getLibraryFragment());
@ -56,7 +72,7 @@ public class SongsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFrag
@Override @Override
public void onMediaStoreChanged() { public void onMediaStoreChanged() {
getAdapter().swapDataSet(SongLoader.getAllSongs(getActivity())); getLoaderManager().restartLoader(LOADER_ID, null, this);
} }
@Override @Override
@ -99,4 +115,34 @@ public class SongsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFrag
getLayoutManager().setSpanCount(gridSize); getLayoutManager().setSpanCount(gridSize);
getAdapter().notifyDataSetChanged(); getAdapter().notifyDataSetChanged();
} }
@DebugLog
@Override
public Loader<ArrayList<Song>> onCreateLoader(int id, Bundle args) {
return new AsyncSongLoader(getActivity());
}
@DebugLog
@Override
public void onLoadFinished(Loader<ArrayList<Song>> loader, ArrayList<Song> data) {
getAdapter().swapDataSet(data);
}
@DebugLog
@Override
public void onLoaderReset(Loader<ArrayList<Song>> loader) {
getAdapter().swapDataSet(new ArrayList<Song>());
}
private static class AsyncSongLoader extends WrappedAsyncTaskLoader<ArrayList<Song>> {
public AsyncSongLoader(Context context) {
super(context);
}
@DebugLog
@Override
public ArrayList<Song> loadInBackground() {
return SongLoader.getAllSongs(getContext());
}
}
} }

View file

@ -205,6 +205,10 @@ public class MusicUtil {
} }
} }
public static boolean isFavoritePlaylist(@NonNull final Context context, @NonNull final Playlist playlist) {
return playlist.name.equals(context.getString(R.string.favorites));
}
public static Playlist getFavoritesPlaylist(@NonNull final Context context) { public static Playlist getFavoritesPlaylist(@NonNull final Context context) {
return PlaylistLoader.getPlaylist(context, context.getString(R.string.favorites)); return PlaylistLoader.getPlaylist(context, context.getString(R.string.favorites));
} }

View file

@ -5,7 +5,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="bottom" android:gravity="bottom"
sothree:umanoOverlay="false" sothree:umanoOverlay="false"
sothree:umanoPanelHeight="@dimen/mini_player_height" sothree:umanoPanelHeight="0dp"
sothree:umanoShadowHeight="@dimen/card_elevation"> sothree:umanoShadowHeight="@dimen/card_elevation">
<FrameLayout <FrameLayout