The search now loads results async.
This commit is contained in:
parent
aa67b6cd35
commit
9eb147625c
2 changed files with 103 additions and 51 deletions
|
|
@ -20,9 +20,6 @@ import com.kabouzeid.gramophone.glide.SongGlideRequest;
|
||||||
import com.kabouzeid.gramophone.glide.artistimage.ArtistImage;
|
import com.kabouzeid.gramophone.glide.artistimage.ArtistImage;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
import com.kabouzeid.gramophone.helper.menu.SongMenuHelper;
|
import com.kabouzeid.gramophone.helper.menu.SongMenuHelper;
|
||||||
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
|
||||||
import com.kabouzeid.gramophone.loader.ArtistLoader;
|
|
||||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
|
||||||
import com.kabouzeid.gramophone.model.Album;
|
import com.kabouzeid.gramophone.model.Album;
|
||||||
import com.kabouzeid.gramophone.model.Artist;
|
import com.kabouzeid.gramophone.model.Artist;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
|
|
@ -31,55 +28,36 @@ import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder> {
|
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder> {
|
||||||
|
|
||||||
private static final int HEADER = 0;
|
private static final int HEADER = 0;
|
||||||
private static final int ALBUM = 1;
|
private static final int ALBUM = 1;
|
||||||
private static final int ARTIST = 2;
|
private static final int ARTIST = 2;
|
||||||
private static final int SONG = 3;
|
private static final int SONG = 3;
|
||||||
|
|
||||||
private final AppCompatActivity activity;
|
private final AppCompatActivity activity;
|
||||||
private List results = Collections.emptyList();
|
private List<Object> dataSet;
|
||||||
|
|
||||||
public SearchAdapter(@NonNull AppCompatActivity activity) {
|
public SearchAdapter(@NonNull AppCompatActivity activity, @NonNull List<Object> dataSet) {
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
|
this.dataSet = dataSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public void swapDataSet(@NonNull List<Object> dataSet) {
|
||||||
public void search(@NonNull String query) {
|
this.dataSet = dataSet;
|
||||||
results = new ArrayList();
|
|
||||||
if (!query.trim().equals("")) {
|
|
||||||
List songs = SongLoader.getSongs(activity, query);
|
|
||||||
if (!songs.isEmpty()) {
|
|
||||||
results.add(activity.getResources().getString(R.string.songs));
|
|
||||||
results.addAll(songs);
|
|
||||||
}
|
|
||||||
|
|
||||||
List artists = ArtistLoader.getArtists(activity, query);
|
|
||||||
if (!artists.isEmpty()) {
|
|
||||||
results.add(activity.getResources().getString(R.string.artists));
|
|
||||||
results.addAll(artists);
|
|
||||||
}
|
|
||||||
|
|
||||||
List albums = AlbumLoader.getAlbums(activity, query);
|
|
||||||
if (!albums.isEmpty()) {
|
|
||||||
results.add(activity.getResources().getString(R.string.albums));
|
|
||||||
results.addAll(albums);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemViewType(int position) {
|
public int getItemViewType(int position) {
|
||||||
if (results.get(position) instanceof Album) return ALBUM;
|
if (dataSet.get(position) instanceof Album) return ALBUM;
|
||||||
if (results.get(position) instanceof Artist) return ARTIST;
|
if (dataSet.get(position) instanceof Artist) return ARTIST;
|
||||||
if (results.get(position) instanceof Song) return SONG;
|
if (dataSet.get(position) instanceof Song) return SONG;
|
||||||
return HEADER;
|
return HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +74,7 @@ public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder
|
||||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||||
switch (getItemViewType(position)) {
|
switch (getItemViewType(position)) {
|
||||||
case ALBUM:
|
case ALBUM:
|
||||||
final Album album = (Album) results.get(position);
|
final Album album = (Album) dataSet.get(position);
|
||||||
holder.title.setText(album.getTitle());
|
holder.title.setText(album.getTitle());
|
||||||
holder.text.setText(album.getArtistName());
|
holder.text.setText(album.getArtistName());
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||||
|
|
@ -104,7 +82,7 @@ public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder
|
||||||
.into(holder.image);
|
.into(holder.image);
|
||||||
break;
|
break;
|
||||||
case ARTIST:
|
case ARTIST:
|
||||||
final Artist artist = (Artist) results.get(position);
|
final Artist artist = (Artist) dataSet.get(position);
|
||||||
holder.title.setText(artist.name);
|
holder.title.setText(artist.name);
|
||||||
holder.text.setText(MusicUtil.getArtistInfoString(activity, artist));
|
holder.text.setText(MusicUtil.getArtistInfoString(activity, artist));
|
||||||
Glide.with(activity)
|
Glide.with(activity)
|
||||||
|
|
@ -118,19 +96,19 @@ public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder
|
||||||
.into(holder.image);
|
.into(holder.image);
|
||||||
break;
|
break;
|
||||||
case SONG:
|
case SONG:
|
||||||
final Song song = (Song) results.get(position);
|
final Song song = (Song) dataSet.get(position);
|
||||||
holder.title.setText(song.title);
|
holder.title.setText(song.title);
|
||||||
holder.text.setText(song.albumName);
|
holder.text.setText(song.albumName);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
holder.title.setText(results.get(position).toString());
|
holder.title.setText(dataSet.get(position).toString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return results.size();
|
return dataSet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends MediaEntryViewHolder {
|
public class ViewHolder extends MediaEntryViewHolder {
|
||||||
|
|
@ -154,7 +132,7 @@ public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder
|
||||||
menu.setOnClickListener(new SongMenuHelper.OnClickSongMenu(activity) {
|
menu.setOnClickListener(new SongMenuHelper.OnClickSongMenu(activity) {
|
||||||
@Override
|
@Override
|
||||||
public Song getSong() {
|
public Song getSong() {
|
||||||
return (Song) results.get(getAdapterPosition());
|
return (Song) dataSet.get(getAdapterPosition());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -180,7 +158,7 @@ public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Object item = results.get(getAdapterPosition());
|
Object item = dataSet.get(getAdapterPosition());
|
||||||
switch (getItemViewType()) {
|
switch (getItemViewType()) {
|
||||||
case ALBUM:
|
case ALBUM:
|
||||||
NavigationUtil.goToAlbum(activity,
|
NavigationUtil.goToAlbum(activity,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities;
|
package com.kabouzeid.gramophone.ui.activities;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
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.v4.view.MenuItemCompat;
|
import android.support.v4.view.MenuItemCompat;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
|
@ -16,15 +20,24 @@ import android.widget.TextView;
|
||||||
import com.kabouzeid.appthemehelper.ThemeStore;
|
import com.kabouzeid.appthemehelper.ThemeStore;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.adapter.SearchAdapter;
|
import com.kabouzeid.gramophone.adapter.SearchAdapter;
|
||||||
|
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
||||||
|
import com.kabouzeid.gramophone.loader.ArtistLoader;
|
||||||
|
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||||
|
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
public class SearchActivity extends AbsMusicServiceActivity implements SearchView.OnQueryTextListener {
|
public class SearchActivity extends AbsMusicServiceActivity implements SearchView.OnQueryTextListener, LoaderManager.LoaderCallbacks<List<Object>> {
|
||||||
|
|
||||||
public static final String TAG = SearchActivity.class.getSimpleName();
|
public static final String TAG = SearchActivity.class.getSimpleName();
|
||||||
|
private static final int LOADER_ID = 1;
|
||||||
|
|
||||||
@Bind(R.id.recycler_view)
|
@Bind(R.id.recycler_view)
|
||||||
RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
@Bind(R.id.toolbar)
|
@Bind(R.id.toolbar)
|
||||||
|
|
@ -34,9 +47,7 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
|
||||||
|
|
||||||
SearchView searchView;
|
SearchView searchView;
|
||||||
|
|
||||||
private SearchAdapter searchAdapter;
|
private SearchAdapter adapter;
|
||||||
|
|
||||||
private String lastQuery = "";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
@ -50,8 +61,15 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
|
||||||
setTaskDescriptionColorAuto();
|
setTaskDescriptionColorAuto();
|
||||||
|
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||||
searchAdapter = new SearchAdapter(this);
|
adapter = new SearchAdapter(this, Collections.emptyList());
|
||||||
recyclerView.setAdapter(searchAdapter);
|
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||||
|
@Override
|
||||||
|
public void onChanged() {
|
||||||
|
super.onChanged();
|
||||||
|
empty.setVisibility(adapter.getItemCount() < 1 ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
recyclerView.setOnTouchListener(new View.OnTouchListener() {
|
recyclerView.setOnTouchListener(new View.OnTouchListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -62,6 +80,8 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
|
||||||
});
|
});
|
||||||
|
|
||||||
setUpToolBar();
|
setUpToolBar();
|
||||||
|
|
||||||
|
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpToolBar() {
|
private void setUpToolBar() {
|
||||||
|
|
@ -106,17 +126,18 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
|
||||||
}
|
}
|
||||||
|
|
||||||
private void search(@NonNull String query) {
|
private void search(@NonNull String query) {
|
||||||
lastQuery = query;
|
Loader loader = getSupportLoaderManager().getLoader(LOADER_ID);
|
||||||
if (searchAdapter != null) {
|
AsyncSearchResultLoader asyncSearchResultLoader = (AsyncSearchResultLoader) loader;
|
||||||
searchAdapter.search(query);
|
asyncSearchResultLoader.setQuery(query);
|
||||||
empty.setVisibility(searchAdapter.getItemCount() < 1 ? View.VISIBLE : View.GONE);
|
asyncSearchResultLoader.forceLoad();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMediaStoreChanged() {
|
public void onMediaStoreChanged() {
|
||||||
super.onMediaStoreChanged();
|
super.onMediaStoreChanged();
|
||||||
search(lastQuery);
|
Loader loader = getSupportLoaderManager().getLoader(LOADER_ID);
|
||||||
|
AsyncSearchResultLoader asyncSearchResultLoader = (AsyncSearchResultLoader) loader;
|
||||||
|
asyncSearchResultLoader.forceLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -137,4 +158,57 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
|
||||||
searchView.clearFocus();
|
searchView.clearFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Loader<List<Object>> onCreateLoader(int id, Bundle args) {
|
||||||
|
return new AsyncSearchResultLoader(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadFinished(Loader<List<Object>> loader, List<Object> data) {
|
||||||
|
adapter.swapDataSet(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoaderReset(Loader<List<Object>> loader) {
|
||||||
|
adapter.swapDataSet(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class AsyncSearchResultLoader extends WrappedAsyncTaskLoader<List<Object>> {
|
||||||
|
private String query;
|
||||||
|
|
||||||
|
public AsyncSearchResultLoader(Context context) {
|
||||||
|
super(context);
|
||||||
|
setUpdateThrottle(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuery(@Nullable String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Object> loadInBackground() {
|
||||||
|
List<Object> results = new ArrayList<>();
|
||||||
|
if (query != null && !query.trim().equals("")) {
|
||||||
|
List songs = SongLoader.getSongs(getContext(), query);
|
||||||
|
if (!songs.isEmpty()) {
|
||||||
|
results.add(getContext().getResources().getString(R.string.songs));
|
||||||
|
results.addAll(songs);
|
||||||
|
}
|
||||||
|
|
||||||
|
List artists = ArtistLoader.getArtists(getContext(), query);
|
||||||
|
if (!artists.isEmpty()) {
|
||||||
|
results.add(getContext().getResources().getString(R.string.artists));
|
||||||
|
results.addAll(artists);
|
||||||
|
}
|
||||||
|
|
||||||
|
List albums = AlbumLoader.getAlbums(getContext(), query);
|
||||||
|
if (!albums.isEmpty()) {
|
||||||
|
results.add(getContext().getResources().getString(R.string.albums));
|
||||||
|
results.addAll(albums);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue