Album and artist detail activities load their data async now.

This commit is contained in:
Karim Abou Zeid 2016-03-20 23:43:11 +01:00
commit aa67b6cd35
4 changed files with 171 additions and 64 deletions

View file

@ -55,6 +55,8 @@ public class ArtistSongAdapter extends ArrayAdapter<Song> implements MaterialCab
public void swapDataSet(ArrayList<Song> dataSet) {
this.dataSet = dataSet;
clear();
addAll(dataSet);
notifyDataSetChanged();
}

View file

@ -94,7 +94,7 @@ public class Song implements Parcelable {
", year=" + year +
", duration=" + duration +
", data='" + data + '\'' +
", getDateModified=" + dateModified +
", dateModified=" + dateModified +
", albumId=" + albumId +
", albumName='" + albumName + '\'' +
", artistId=" + artistId +

View file

@ -1,9 +1,12 @@
package com.kabouzeid.gramophone.ui.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
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.RecyclerView;
import android.support.v7.widget.Toolbar;
@ -32,6 +35,7 @@ import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
import com.kabouzeid.gramophone.loader.AlbumLoader;
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
import com.kabouzeid.gramophone.ui.activities.tageditor.AbsTagEditorActivity;
@ -42,14 +46,16 @@ import com.kabouzeid.gramophone.util.Util;
import butterknife.Bind;
import butterknife.ButterKnife;
import hugo.weaving.DebugLog;
/**
* Be careful when changing things in this Activity!
*/
public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder {
public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder, LoaderManager.LoaderCallbacks<Album> {
public static final String TAG = AlbumDetailActivity.class.getSimpleName();
private static final int TAG_EDITOR_REQUEST = 2001;
private static final int LOADER_ID = 1;
public static final String EXTRA_ALBUM_ID = "extra_album_id";
@ -83,10 +89,11 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
supportPostponeEnterTransition();
getAlbumFromIntentExtras();
setUpObservableListViewParams();
setUpToolBar();
setUpViews();
getSupportLoaderManager().initLoader(LOADER_ID, getIntent().getExtras(), this);
}
@Override
@ -120,15 +127,6 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
}
};
private void getAlbumFromIntentExtras() {
Bundle intentExtras = getIntent().getExtras();
final int albumId = intentExtras.getInt(EXTRA_ALBUM_ID);
album = AlbumLoader.getAlbum(this, albumId);
if (album.songs.isEmpty()) {
finish();
}
}
private void setUpObservableListViewParams() {
albumArtViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
toolbarColor = DialogUtils.resolveColor(this, R.attr.defaultFooterColor);
@ -141,14 +139,12 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
}
private void setUpViews() {
albumTitleView.setText(album.getTitle());
setUpRecyclerViewView();
setUpRecyclerView();
setUpSongsAdapter();
loadAlbumCover();
}
private void loadAlbumCover() {
SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
SongGlideRequest.Builder.from(Glide.with(this), getAlbum().safeGetFirstSong())
.checkIgnoreMediaStore(this)
.generatePalette(this).build()
.dontAnimate()
@ -187,7 +183,7 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
return toolbarColor;
}
private void setUpRecyclerViewView() {
private void setUpRecyclerView() {
setUpRecyclerViewPadding();
recyclerView.setScrollViewCallbacks(observableScrollViewCallbacks);
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
@ -215,7 +211,7 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
}
private void setUpSongsAdapter() {
adapter = new AlbumSongAdapter(this, album.songs, R.layout.item_list, false, this);
adapter = new AlbumSongAdapter(this, getAlbum().songs, R.layout.item_list, false, this);
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
recyclerView.setAdapter(adapter);
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@ -227,11 +223,8 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
});
}
private void refresh() {
album = AlbumLoader.getAlbum(this, album.getId());
albumTitleView.setText(album.getTitle());
loadAlbumCover();
adapter.swapDataSet(album.songs);
private void reload() {
getSupportLoaderManager().restartLoader(LOADER_ID, getIntent().getExtras(), this);
}
@Override
@ -258,11 +251,11 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
return true;
case R.id.action_tag_editor:
Intent intent = new Intent(this, AlbumTagEditorActivity.class);
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.getId());
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, getAlbum().getId());
startActivityForResult(intent, TAG_EDITOR_REQUEST);
return true;
case R.id.action_go_to_artist:
NavigationUtil.goToArtist(this, album.getArtistId());
NavigationUtil.goToArtist(this, getAlbum().getArtistId());
return true;
}
return super.onOptionsItemSelected(item);
@ -272,11 +265,12 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAG_EDITOR_REQUEST) {
refresh();
reload();
setResult(RESULT_OK);
}
}
@NonNull
@Override
public MaterialCab openCab(int menuRes, @NonNull final MaterialCab.Callback callback) {
if (cab != null && cab.isActive()) cab.finish();
@ -317,7 +311,7 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
@Override
public void onMediaStoreChanged() {
super.onMediaStoreChanged();
refresh();
reload();
}
@Override
@ -325,4 +319,53 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
super.setStatusbarColor(color);
setLightStatusbar(false);
}
private void setAlbum(Album album) {
this.album = album;
loadAlbumCover();
albumTitleView.setText(album.getTitle());
adapter.swapDataSet(album.songs);
}
private Album getAlbum() {
if (album == null) album = new Album();
return album;
}
@Override
public Loader<Album> onCreateLoader(int id, Bundle args) {
return new AsyncAlbumLoader(this, args.getInt(EXTRA_ALBUM_ID));
}
@DebugLog
@Override
public void onLoadFinished(Loader<Album> loader, Album data) {
supportStartPostponedEnterTransition();
setAlbum(data);
if (getAlbum().songs.isEmpty()) {
finish();
}
}
@DebugLog
@Override
public void onLoaderReset(Loader<Album> loader) {
this.album = new Album();
adapter.swapDataSet(album.songs);
}
private static class AsyncAlbumLoader extends WrappedAsyncTaskLoader<Album> {
private final int albumId;
public AsyncAlbumLoader(Context context, int albumId) {
super(context);
this.albumId = albumId;
}
@DebugLog
@Override
public Album loadInBackground() {
return AlbumLoader.getAlbum(getContext(), albumId);
}
}
}

View file

@ -1,10 +1,13 @@
package com.kabouzeid.gramophone.ui.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
@ -45,6 +48,7 @@ import com.kabouzeid.gramophone.loader.ArtistAlbumLoader;
import com.kabouzeid.gramophone.loader.ArtistLoader;
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.model.Song;
@ -58,6 +62,7 @@ import java.util.ArrayList;
import butterknife.Bind;
import butterknife.ButterKnife;
import hugo.weaving.DebugLog;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
@ -65,9 +70,10 @@ import retrofit2.Response;
/**
* Be careful when changing things in this Activity!
*/
public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder {
public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder, LoaderManager.LoaderCallbacks<ArtistDetailActivity.ArtistData> {
public static final String TAG = ArtistDetailActivity.class.getSimpleName();
private static final int LOADER_ID = 1;
public static final String EXTRA_ARTIST_ID = "extra_artist_id";
@ -92,7 +98,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
private int toolbarColor;
private float toolbarAlpha;
private Artist artist;
private ArtistData artistData;
@Nullable
private Spanned biography;
private HorizontalAlbumAdapter albumAdapter;
@ -106,13 +112,16 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
setDrawUnderStatusbar(true);
ButterKnife.bind(this);
supportPostponeEnterTransition();
lastFMRestClient = new LastFMRestClient(this);
getArtistFromIntentExtras();
initViews();
setUpObservableListViewParams();
setUpViews();
setUpToolbar();
getSupportLoaderManager().initLoader(LOADER_ID, getIntent().getExtras(), this);
}
@Override
@ -163,11 +172,8 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
}
private void setUpViews() {
artistName.setText(artist.name);
setUpArtistImageAndApplyPalette(false);
setUpSongListView();
setUpAlbumRecyclerView();
loadBiography();
}
private void setUpSongListView() {
@ -175,7 +181,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
songListView.setScrollViewCallbacks(observableScrollViewCallbacks);
songListView.addHeaderView(songListHeader);
songAdapter = new ArtistSongAdapter(this, loadSongDataSet(), this);
songAdapter = new ArtistSongAdapter(this, getArtistData().songs, this);
songListView.setAdapter(songAdapter);
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
@ -194,7 +200,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
private void setUpAlbumRecyclerView() {
albumRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
albumAdapter = new HorizontalAlbumAdapter(this, loadAlbumDataSet(), this);
albumAdapter = new HorizontalAlbumAdapter(this, getArtistData().albums, this);
albumRecyclerView.setAdapter(albumAdapter);
albumAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
@ -205,21 +211,12 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
});
}
private void reloadDataSets() {
songAdapter.swapDataSet(loadSongDataSet());
albumAdapter.swapDataSet(loadAlbumDataSet());
}
private ArrayList<Song> loadSongDataSet() {
return ArtistSongLoader.getArtistSongList(this, artist.id);
}
private ArrayList<Album> loadAlbumDataSet() {
return ArtistAlbumLoader.getAlbums(this, artist.id);
private void reload() {
getSupportLoaderManager().restartLoader(LOADER_ID, getIntent().getExtras(), this);
}
private void loadBiography() {
lastFMRestClient.getApiService().getArtistInfo(artist.name, null).enqueue(new Callback<LastFmArtist>() {
lastFMRestClient.getApiService().getArtistInfo(getArtistData().artist.name, null).enqueue(new Callback<LastFmArtist>() {
@Override
public void onResponse(Call<LastFmArtist> call, Response<LastFmArtist> response) {
LastFmArtist lastFmArtist = response.body();
@ -243,23 +240,23 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
private MaterialDialog getBiographyDialog() {
return new MaterialDialog.Builder(ArtistDetailActivity.this)
.title(artist.name)
.title(getArtistData().artist.name)
.content(biography != null ? biography : "")
.positiveText(android.R.string.ok)
.build();
}
private void setUpArtistImageAndApplyPalette(final boolean forceDownload) {
private void loadArtistImage(final boolean forceDownload) {
if (forceDownload) {
ArtistSignatureUtil.getInstance(this).updateArtistSignature(artist.name);
ArtistSignatureUtil.getInstance(this).updateArtistSignature(getArtistData().artist.name);
}
Glide.with(this)
.load(new ArtistImage(artist.name, forceDownload))
.load(new ArtistImage(getArtistData().artist.name, forceDownload))
.asBitmap()
.transcode(new BitmapPaletteTranscoder(this), BitmapPaletteWrapper.class)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.placeholder(R.drawable.default_artist_image)
.signature(ArtistSignatureUtil.getInstance(this).getArtistSignature(artist.name))
.signature(ArtistSignatureUtil.getInstance(this).getArtistSignature(getArtistData().artist.name))
.dontAnimate()
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.listener(new RequestListener<ArtistImage, BitmapPaletteWrapper>() {
@ -291,7 +288,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
reloadDataSets();
reload();
}
}
@ -308,15 +305,6 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
setTaskDescriptionColor(color);
}
private void getArtistFromIntentExtras() {
Bundle intentExtras = getIntent().getExtras();
final int artistId = intentExtras.getInt(EXTRA_ARTIST_ID);
artist = ArtistLoader.getArtist(this, artistId);
if (artist.id == -1) {
finish();
}
}
private void setUpToolbar() {
setSupportActionBar(toolbar);
//noinspection ConstantConditions
@ -355,12 +343,13 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
return true;
case R.id.action_re_download_artist_image:
Toast.makeText(ArtistDetailActivity.this, getResources().getString(R.string.updating), Toast.LENGTH_SHORT).show();
setUpArtistImageAndApplyPalette(true);
loadArtistImage(true);
return true;
}
return super.onOptionsItemSelected(item);
}
@NonNull
@Override
public MaterialCab openCab(int menuRes, @NonNull final MaterialCab.Callback callback) {
if (cab != null && cab.isActive()) cab.finish();
@ -401,7 +390,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
@Override
public void onMediaStoreChanged() {
super.onMediaStoreChanged();
reloadDataSets();
reload();
}
@Override
@ -409,4 +398,77 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
super.setStatusbarColor(color);
setLightStatusbar(false);
}
private void setArtistData(ArtistData artistData) {
this.artistData = artistData;
loadArtistImage(false);
loadBiography();
artistName.setText(artistData.artist.name);
songAdapter.swapDataSet(artistData.songs);
albumAdapter.swapDataSet(artistData.albums);
}
private ArtistData getArtistData() {
if (artistData == null) artistData = new ArtistData();
return artistData;
}
@Override
public Loader<ArtistData> onCreateLoader(int id, Bundle args) {
return new AsyncArtistDataLoader(this, args.getInt(EXTRA_ARTIST_ID));
}
@DebugLog
@Override
public void onLoadFinished(Loader<ArtistData> loader, ArtistData data) {
supportStartPostponedEnterTransition();
setArtistData(data);
if (getArtistData().albums.isEmpty()) {
finish();
}
}
@DebugLog
@Override
public void onLoaderReset(Loader<ArtistData> loader) {
this.artistData = new ArtistData();
songAdapter.swapDataSet(artistData.songs);
albumAdapter.swapDataSet(artistData.albums);
}
private static class AsyncArtistDataLoader extends WrappedAsyncTaskLoader<ArtistData> {
private final int artistId;
public AsyncArtistDataLoader(Context context, int artistId) {
super(context);
this.artistId = artistId;
}
@DebugLog
@Override
public ArtistData loadInBackground() {
Artist artist = ArtistLoader.getArtist(getContext(), artistId);
ArrayList<Song> songs = ArtistSongLoader.getArtistSongList(getContext(), artist.id);
ArrayList<Album> albums = ArtistAlbumLoader.getAlbums(getContext(), artist.id);
return new ArtistData(artist, songs, albums);
}
}
static class ArtistData {
public final Artist artist;
public final ArrayList<Song> songs;
public final ArrayList<Album> albums;
private ArtistData() {
artist = new Artist();
songs = new ArrayList<>();
albums = new ArrayList<>();
}
private ArtistData(Artist artist, ArrayList<Song> songs, ArrayList<Album> albums) {
this.artist = artist;
this.songs = songs;
this.albums = albums;
}
}
}