From fbb95edd918d2c9dd978202caba9e0065db003f9 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Thu, 28 May 2015 19:22:08 -0700 Subject: #509 Convert search to use RecyclerView --- .../dsub/activity/SubsonicFragmentActivity.java | 1 - .../daneren2005/dsub/adapter/ArtistAdapter.java | 197 ++++++++++-------- .../daneren2005/dsub/adapter/ArtistAdapter2.java | 128 ------------ .../daneren2005/dsub/adapter/SearchAdapter.java | 114 +++++++++++ .../daneren2005/dsub/adapter/SectionAdapter.java | 1 + .../daneren2005/dsub/fragments/SearchFragment.java | 227 ++++++--------------- .../dsub/fragments/SelectArtistFragment.java | 12 +- .../dsub/fragments/SelectRecyclerFragment.java | 39 +--- .../dsub/fragments/SimilarArtistFragment.java | 4 +- .../dsub/fragments/SubsonicFragment.java | 42 ++++ app/src/main/res/layout/basic_header.xml | 4 +- 11 files changed, 347 insertions(+), 422 deletions(-) delete mode 100644 app/src/main/java/github/daneren2005/dsub/adapter/ArtistAdapter2.java create mode 100644 app/src/main/java/github/daneren2005/dsub/adapter/SearchAdapter.java (limited to 'app/src') diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java index 83d5bce8..774a8def 100644 --- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java +++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java @@ -340,7 +340,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity { if (query != null) { ((SearchFragment)currentFragment).search(query, autoplay); } else { - ((SearchFragment)currentFragment).populateList(); if (requestsearch) { onSearchRequested(); } diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/ArtistAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/ArtistAdapter.java index 4d469faf..0563b38d 100644 --- a/app/src/main/java/github/daneren2005/dsub/adapter/ArtistAdapter.java +++ b/app/src/main/java/github/daneren2005/dsub/adapter/ArtistAdapter.java @@ -1,97 +1,128 @@ /* - This file is part of Subsonic. + This file is part of Subsonic. + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Subsonic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson +*/ - Subsonic is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Subsonic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Subsonic. If not, see . - - Copyright 2010 (C) Sindre Mehus - */ package github.daneren2005.dsub.adapter; import android.content.Context; -import github.daneren2005.dsub.R; -import java.util.List; +import android.support.v7.widget.PopupMenu; +import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.SectionIndexer; +import android.widget.TextView; + +import java.util.List; + +import github.daneren2005.dsub.R; import github.daneren2005.dsub.domain.Artist; +import github.daneren2005.dsub.domain.MusicFolder; +import github.daneren2005.dsub.util.Util; import github.daneren2005.dsub.view.ArtistView; +import github.daneren2005.dsub.view.UpdateView; + +public class ArtistAdapter extends SectionAdapter { + public static int VIEW_TYPE_ARTIST = 4; + + private List musicFolders; + private OnMusicFolderChanged onMusicFolderChanged; + + public ArtistAdapter(Context context, List artists, OnItemClickedListener listener) { + this(context, artists, null, listener, null); + } + + public ArtistAdapter(Context context, List artists, List musicFolders, OnItemClickedListener onItemClickedListener, OnMusicFolderChanged onMusicFolderChanged) { + super(context, artists); + this.musicFolders = musicFolders; + this.onItemClickedListener = onItemClickedListener; + this.onMusicFolderChanged = onMusicFolderChanged; + + if(musicFolders != null) { + this.singleSectionHeader = true; + } + } + + @Override + public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { + final View header = LayoutInflater.from(context).inflate(R.layout.select_artist_header, parent, false); + header.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + PopupMenu popup = new PopupMenu(context, header); + + popup.getMenu().add(R.string.select_artist_all_folders); + for (MusicFolder musicFolder : musicFolders) { + popup.getMenu().add(musicFolder.getName()); + } + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + for (MusicFolder musicFolder : musicFolders) { + if(item.getTitle().equals(musicFolder.getName())) { + if(onMusicFolderChanged != null) { + onMusicFolderChanged.onMusicFolderChanged(musicFolder); + } + return true; + } + } + + if(onMusicFolderChanged != null) { + onMusicFolderChanged.onMusicFolderChanged(null); + } + return true; + } + }); + popup.show(); + } + }); + + return new UpdateView.UpdateViewHolder(header, false); + } + @Override + public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String header) { + TextView folderName = (TextView) holder.getView().findViewById(R.id.select_artist_folder_2); -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.Set; - -/** - * @author Sindre Mehus - */ -public class ArtistAdapter extends ArrayAdapter implements SectionIndexer { - - private final Context activity; - - // Both arrays are indexed by section ID. - private final Object[] sections; - private final Integer[] positions; - - public ArtistAdapter(Context activity, List artists) { - super(activity, R.layout.basic_list_item, artists); - this.activity = activity; - - Set sectionSet = new LinkedHashSet(30); - List positionList = new ArrayList(30); - for (int i = 0; i < artists.size(); i++) { - Artist artist = artists.get(i); - String index = artist.getIndex(); - if (!sectionSet.contains(index)) { - sectionSet.add(index); - positionList.add(i); - } - } - sections = sectionSet.toArray(new Object[sectionSet.size()]); - positions = positionList.toArray(new Integer[positionList.size()]); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - Artist entry = getItem(position); - ArtistView view; - if (convertView != null && convertView instanceof ArtistView) { - view = (ArtistView) convertView; + String musicFolderId = Util.getSelectedMusicFolderId(context); + if(musicFolderId != null) { + for (MusicFolder musicFolder : musicFolders) { + if (musicFolder.getId().equals(musicFolderId)) { + folderName.setText(musicFolder.getName()); + break; + } + } } else { - view = new ArtistView(activity); + folderName.setText(R.string.select_artist_all_folders); } - view.setObject(entry); - return view; - } - + } + + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + return new UpdateView.UpdateViewHolder(new ArtistView(context)); + } + @Override - public Object[] getSections() { - return sections; - } - - @Override - public int getPositionForSection(int section) { - section = Math.min(section, positions.length - 1); - return positions[section]; - } - - @Override - public int getSectionForPosition(int pos) { - for (int i = 0; i < sections.length - 1; i++) { - if (pos < positions[i + 1]) { - return i; - } - } - return sections.length - 1; - } + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Artist item, int viewType) { + holder.getUpdateView().setObject(item); + } + + @Override + public int getItemViewType(Artist item) { + return VIEW_TYPE_ARTIST; + } + + public interface OnMusicFolderChanged { + void onMusicFolderChanged(MusicFolder musicFolder); + } } diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/ArtistAdapter2.java b/app/src/main/java/github/daneren2005/dsub/adapter/ArtistAdapter2.java deleted file mode 100644 index 88b3ae28..00000000 --- a/app/src/main/java/github/daneren2005/dsub/adapter/ArtistAdapter2.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - This file is part of Subsonic. - Subsonic is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - Subsonic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson -*/ - -package github.daneren2005.dsub.adapter; - -import android.content.Context; -import android.support.v7.widget.PopupMenu; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import java.util.List; - -import github.daneren2005.dsub.R; -import github.daneren2005.dsub.domain.Artist; -import github.daneren2005.dsub.domain.MusicFolder; -import github.daneren2005.dsub.util.Util; -import github.daneren2005.dsub.view.ArtistView; -import github.daneren2005.dsub.view.UpdateView; - -public class ArtistAdapter2 extends SectionAdapter { - public static int VIEW_TYPE_ARTIST = 1; - - private List musicFolders; - private OnMusicFolderChanged onMusicFolderChanged; - - public ArtistAdapter2(Context context, List artists, OnItemClickedListener listener) { - this(context, artists, null, listener, null); - } - - public ArtistAdapter2(Context context, List artists, List musicFolders, OnItemClickedListener onItemClickedListener, OnMusicFolderChanged onMusicFolderChanged) { - super(context, artists); - this.musicFolders = musicFolders; - this.onItemClickedListener = onItemClickedListener; - this.onMusicFolderChanged = onMusicFolderChanged; - - if(musicFolders != null) { - this.singleSectionHeader = true; - } - } - - @Override - public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { - final View header = LayoutInflater.from(context).inflate(R.layout.select_artist_header, parent, false); - header.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PopupMenu popup = new PopupMenu(context, header); - - popup.getMenu().add(R.string.select_artist_all_folders); - for (MusicFolder musicFolder : musicFolders) { - popup.getMenu().add(musicFolder.getName()); - } - - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - for (MusicFolder musicFolder : musicFolders) { - if(item.getTitle().equals(musicFolder.getName())) { - if(onMusicFolderChanged != null) { - onMusicFolderChanged.onMusicFolderChanged(musicFolder); - } - return true; - } - } - - if(onMusicFolderChanged != null) { - onMusicFolderChanged.onMusicFolderChanged(null); - } - return true; - } - }); - popup.show(); - } - }); - - return new UpdateView.UpdateViewHolder(header, false); - } - @Override - public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String header) { - TextView folderName = (TextView) holder.getView().findViewById(R.id.select_artist_folder_2); - - String musicFolderId = Util.getSelectedMusicFolderId(context); - if(musicFolderId != null) { - for (MusicFolder musicFolder : musicFolders) { - if (musicFolder.getId().equals(musicFolderId)) { - folderName.setText(musicFolder.getName()); - break; - } - } - } else { - folderName.setText(R.string.select_artist_all_folders); - } - } - - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - return new UpdateView.UpdateViewHolder(new ArtistView(context)); - } - - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Artist item, int viewType) { - holder.getUpdateView().setObject(item); - } - - @Override - public int getItemViewType(Artist item) { - return VIEW_TYPE_ARTIST; - } - - public interface OnMusicFolderChanged { - void onMusicFolderChanged(MusicFolder musicFolder); - } -} diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/SearchAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/SearchAdapter.java new file mode 100644 index 00000000..f395216e --- /dev/null +++ b/app/src/main/java/github/daneren2005/dsub/adapter/SearchAdapter.java @@ -0,0 +1,114 @@ +/* + This file is part of Subsonic. + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Subsonic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson +*/ + +package github.daneren2005.dsub.adapter; + +import android.content.Context; +import android.content.res.Resources; +import android.view.ViewGroup; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import github.daneren2005.dsub.R; +import github.daneren2005.dsub.domain.MusicDirectory.Entry; +import github.daneren2005.dsub.domain.SearchResult; +import github.daneren2005.dsub.util.ImageLoader; +import github.daneren2005.dsub.view.AlbumView; +import github.daneren2005.dsub.view.ArtistView; +import github.daneren2005.dsub.view.SongView; +import github.daneren2005.dsub.view.UpdateView; + +import static github.daneren2005.dsub.adapter.ArtistAdapter.VIEW_TYPE_ARTIST; +import static github.daneren2005.dsub.adapter.EntryGridAdapter.VIEW_TYPE_ALBUM_CELL; +import static github.daneren2005.dsub.adapter.EntryGridAdapter.VIEW_TYPE_ALBUM_LINE; +import static github.daneren2005.dsub.adapter.EntryGridAdapter.VIEW_TYPE_SONG; + +public class SearchAdapter extends SectionAdapter { + private SearchResult searchResult; + private ImageLoader imageLoader; + private boolean largeAlbums; + + public SearchAdapter(Context context, SearchResult searchResult, ImageLoader imageLoader, boolean largeAlbums, OnItemClickedListener listener) { + this.context = context; + this.searchResult = searchResult; + this.imageLoader = imageLoader; + this.largeAlbums = largeAlbums; + + this.sections = new ArrayList<>(); + this.headers = new ArrayList<>(); + Resources res = context.getResources(); + if(!searchResult.getArtists().isEmpty()) { + this.sections.add((List) (List) searchResult.getArtists()); + this.headers.add(res.getString(R.string.search_artists)); + } + if(!searchResult.getAlbums().isEmpty()) { + this.sections.add((List) (List) searchResult.getAlbums()); + this.headers.add(res.getString(R.string.search_albums)); + } + if(!searchResult.getSongs().isEmpty()) { + this.sections.add((List) (List) searchResult.getSongs()); + this.headers.add(res.getString(R.string.search_songs)); + } + this.onItemClickedListener = listener; + } + + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + UpdateView updateView = null; + if(viewType == VIEW_TYPE_ALBUM_CELL || viewType == VIEW_TYPE_ALBUM_LINE) { + updateView = new AlbumView(context, viewType == VIEW_TYPE_ALBUM_CELL); + } else if(viewType == VIEW_TYPE_SONG) { + updateView = new SongView(context); + } else if(viewType == VIEW_TYPE_ARTIST) { + updateView = new ArtistView(context); + } + + return new UpdateView.UpdateViewHolder(updateView); + } + + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Serializable item, int viewType) { + UpdateView view = holder.getUpdateView(); + if(viewType == VIEW_TYPE_ALBUM_CELL || viewType == VIEW_TYPE_ALBUM_LINE) { + AlbumView albumView = (AlbumView) view; + albumView.setObject(item, imageLoader); + } else if(viewType == VIEW_TYPE_SONG) { + SongView songView = (SongView) view; + songView.setObject(item, false); + } else if(viewType == VIEW_TYPE_ARTIST) { + view.setObject(item); + } + } + + @Override + public int getItemViewType(Serializable item) { + if(item instanceof Entry) { + Entry entry = (Entry) item; + if (entry.isDirectory()) { + if (largeAlbums) { + return VIEW_TYPE_ALBUM_CELL; + } else { + return VIEW_TYPE_ALBUM_LINE; + } + } else { + return VIEW_TYPE_SONG; + } + } else { + return VIEW_TYPE_ARTIST; + } + } +} diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java index 85a7f18f..293012a2 100644 --- a/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java +++ b/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java @@ -43,6 +43,7 @@ public abstract class SectionAdapter extends RecyclerView.Adapter selected = new ArrayList<>(); + protected SectionAdapter() {} public SectionAdapter(Context context, List section) { this(context, section, false); } diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SearchFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SearchFragment.java index 0f1598dd..20a87e7d 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SearchFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SearchFragment.java @@ -1,12 +1,14 @@ package github.daneren2005.dsub.fragments; -import java.util.ArrayList; -import java.util.List; +import java.io.Serializable; import java.util.Arrays; import android.content.Intent; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; @@ -14,11 +16,13 @@ import android.view.MenuInflater; import android.view.View; import android.view.MenuItem; import android.widget.AdapterView; -import android.widget.ListAdapter; -import android.widget.ListView; import android.net.Uri; import android.view.ViewGroup; import github.daneren2005.dsub.R; +import github.daneren2005.dsub.adapter.ArtistAdapter; +import github.daneren2005.dsub.adapter.EntryGridAdapter; +import github.daneren2005.dsub.adapter.SearchAdapter; +import github.daneren2005.dsub.adapter.SectionAdapter; import github.daneren2005.dsub.domain.Artist; import github.daneren2005.dsub.domain.MusicDirectory; import github.daneren2005.dsub.domain.SearchCritera; @@ -26,40 +30,24 @@ import github.daneren2005.dsub.domain.SearchResult; import github.daneren2005.dsub.service.MusicService; import github.daneren2005.dsub.service.MusicServiceFactory; import github.daneren2005.dsub.service.DownloadService; -import github.daneren2005.dsub.adapter.ArtistAdapter; import github.daneren2005.dsub.util.BackgroundTask; import github.daneren2005.dsub.util.Constants; -import github.daneren2005.dsub.adapter.EntryAdapter; -import github.daneren2005.dsub.adapter.MergeAdapter; import github.daneren2005.dsub.util.TabBackgroundTask; import github.daneren2005.dsub.util.Util; +import github.daneren2005.dsub.view.UpdateView; -public class SearchFragment extends SubsonicFragment { +public class SearchFragment extends SubsonicFragment implements SectionAdapter.OnItemClickedListener { private static final String TAG = SearchFragment.class.getSimpleName(); - private static final int DEFAULT_ARTISTS = 3; - private static final int DEFAULT_ALBUMS = 5; - private static final int DEFAULT_SONGS = 10; - private static final int MAX_ARTISTS = 10; - private static final int MAX_ALBUMS = 20; + private static final int MAX_ALBUMS = 10; private static final int MAX_SONGS = 25; - private ListView list; - - private View artistsHeading; - private View albumsHeading; - private View songsHeading; - private View moreArtistsButton; - private View moreAlbumsButton; - private View moreSongsButton; + + protected RecyclerView recyclerView; + protected SearchAdapter adapter; + protected boolean largeAlbums = false; + private SearchResult searchResult; - private MergeAdapter mergeAdapter; - private ArtistAdapter artistAdapter; - private ListAdapter moreArtistsAdapter; - private EntryAdapter albumAdapter; - private ListAdapter moreAlbumsAdapter; - private ListAdapter moreSongsAdapter; - private EntryAdapter songAdapter; private boolean skipSearch = false; private String currentQuery; @@ -70,6 +58,7 @@ public class SearchFragment extends SubsonicFragment { if(savedInstanceState != null) { searchResult = (SearchResult) savedInstanceState.getSerializable(Constants.FRAGMENT_LIST); } + largeAlbums = Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_LARGE_ALBUM_ART, true); } @Override @@ -80,62 +69,42 @@ public class SearchFragment extends SubsonicFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - rootView = inflater.inflate(R.layout.abstract_list_fragment, container, false); + rootView = inflater.inflate(R.layout.abstract_recycler_fragment, container, false); setTitle(R.string.search_title); - View buttons = inflater.inflate(R.layout.search_buttons, null); - - artistsHeading = buttons.findViewById(R.id.search_artists); - albumsHeading = buttons.findViewById(R.id.search_albums); - songsHeading = buttons.findViewById(R.id.search_songs); - - moreArtistsButton = buttons.findViewById(R.id.search_more_artists); - moreAlbumsButton = buttons.findViewById(R.id.search_more_albums); - moreSongsButton = buttons.findViewById(R.id.search_more_songs); - refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout); refreshLayout.setEnabled(false); - list = (ListView) rootView.findViewById(R.id.fragment_list); + recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_recycler); + setupLayoutManager(recyclerView, largeAlbums); - list.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - if (view == moreArtistsButton) { - expandArtists(); - } else if (view == moreAlbumsButton) { - expandAlbums(); - } else if (view == moreSongsButton) { - expandSongs(); - } else { - Object item = parent.getItemAtPosition(position); - if (item instanceof Artist) { - onArtistSelected((Artist) item, false); - } else if (item instanceof MusicDirectory.Entry) { - MusicDirectory.Entry entry = (MusicDirectory.Entry) item; - if (entry.isDirectory()) { - onAlbumSelected(entry, false); - } else if (entry.isVideo()) { - onVideoSelected(entry); - } else { - onSongSelected(entry, false, true, true, false); - } - - } - } - } - }); - registerForContextMenu(list); + registerForContextMenu(recyclerView); context.onNewIntent(context.getIntent()); if(searchResult != null) { skipSearch = true; - populateList(); + recyclerView.setAdapter(adapter = new SearchAdapter(context, searchResult, getImageLoader(), largeAlbums, this)); } return rootView; } + @Override + public GridLayoutManager.SpanSizeLookup getSpanSizeLookup() { + final int columns = getRecyclerColumnCount(); + return new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + int viewType = adapter.getItemViewType(position); + if(viewType == EntryGridAdapter.VIEW_TYPE_SONG || viewType == EntryGridAdapter.VIEW_TYPE_HEADER || viewType == ArtistAdapter.VIEW_TYPE_ARTIST) { + return columns; + } else { + return 1; + } + } + }; + } + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { menuInflater.inflate(R.menu.search, menu); @@ -156,11 +125,12 @@ public class SearchFragment extends SubsonicFragment { @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, view, menuInfo); + UpdateView targetView = adapter.getContextView(); + menuInfo = new AdapterView.AdapterContextMenuInfo(targetView, 0, 0); - AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; - Object selectedItem = list.getItemAtPosition(info.position); - onCreateContextMenu(menu, view, menuInfo, selectedItem); - if(selectedItem instanceof MusicDirectory.Entry && !((MusicDirectory.Entry) selectedItem).isVideo() && !Util.isOffline(context)) { + Serializable item = adapter.getContextItem(); + onCreateContextMenu(menu, view, menuInfo, item); + if(item instanceof MusicDirectory.Entry && !((MusicDirectory.Entry) item).isVideo() && !Util.isOffline(context)) { menu.removeItem(R.id.song_menu_remove_playlist); } @@ -172,27 +142,37 @@ public class SearchFragment extends SubsonicFragment { if(menuItem.getGroupId() != getSupportTag()) { return false; } - - AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo(); - Object selectedItem = list.getItemAtPosition(info.position); - - if(onContextItemSelected(menuItem, selectedItem)) { + + Serializable item = adapter.getContextItem(); + if(onContextItemSelected(menuItem, item)) { return true; } return true; } - - @Override - public void setPrimaryFragment(boolean primary) { - super.setPrimaryFragment(primary); - } @Override public void refresh(boolean refresh) { context.onNewIntent(context.getIntent()); } + @Override + public void onItemClicked(Serializable item) { + Log.d(TAG, item.getClass().getSimpleName()); + if (item instanceof Artist) { + onArtistSelected((Artist) item, false); + } else if (item instanceof MusicDirectory.Entry) { + MusicDirectory.Entry entry = (MusicDirectory.Entry) item; + if (entry.isDirectory()) { + onAlbumSelected(entry, false); + } else if (entry.isVideo()) { + onVideoSelected(entry); + } else { + onSongSelected(entry, false, true, true, false); + } + } + } + public void search(final String query, final boolean autoplay) { if(skipSearch) { skipSearch = false; @@ -200,9 +180,6 @@ public class SearchFragment extends SubsonicFragment { } currentQuery = query; - mergeAdapter = new MergeAdapter(); - list.setAdapter(mergeAdapter); - BackgroundTask task = new TabBackgroundTask(this) { @Override protected SearchResult doInBackground() throws Throwable { @@ -214,7 +191,7 @@ public class SearchFragment extends SubsonicFragment { @Override protected void done(SearchResult result) { searchResult = result; - populateList(); + recyclerView.setAdapter(adapter = new SearchAdapter(context, searchResult, getImageLoader(), largeAlbums, SearchFragment.this)); if (autoplay) { autoplay(query); } @@ -224,82 +201,6 @@ public class SearchFragment extends SubsonicFragment { task.execute(); } - public void populateList() { - mergeAdapter = new MergeAdapter(); - - if (searchResult != null) { - List artists = searchResult.getArtists(); - if (!artists.isEmpty()) { - mergeAdapter.addView(artistsHeading); - List displayedArtists = new ArrayList(artists.subList(0, Math.min(DEFAULT_ARTISTS, artists.size()))); - artistAdapter = new ArtistAdapter(context, displayedArtists); - mergeAdapter.addAdapter(artistAdapter); - if (artists.size() > DEFAULT_ARTISTS) { - moreArtistsAdapter = mergeAdapter.addView(moreArtistsButton, true); - } - } - - List albums = searchResult.getAlbums(); - if (!albums.isEmpty()) { - mergeAdapter.addView(albumsHeading); - List displayedAlbums = new ArrayList(albums.subList(0, Math.min(DEFAULT_ALBUMS, albums.size()))); - albumAdapter = new EntryAdapter(context, getImageLoader(), displayedAlbums, false); - mergeAdapter.addAdapter(albumAdapter); - if (albums.size() > DEFAULT_ALBUMS) { - moreAlbumsAdapter = mergeAdapter.addView(moreAlbumsButton, true); - } - } - - List songs = searchResult.getSongs(); - if (!songs.isEmpty()) { - mergeAdapter.addView(songsHeading); - List displayedSongs = new ArrayList(songs.subList(0, Math.min(DEFAULT_SONGS, songs.size()))); - songAdapter = new EntryAdapter(context, getImageLoader(), displayedSongs, false); - mergeAdapter.addAdapter(songAdapter); - if (songs.size() > DEFAULT_SONGS) { - moreSongsAdapter = mergeAdapter.addView(moreSongsButton, true); - } - } - - boolean empty = searchResult.getArtists().isEmpty() && searchResult.getAlbums().isEmpty() && searchResult.getSongs().isEmpty(); - if(empty) { - setEmpty(true); - } - } - - list.setAdapter(mergeAdapter); - } - - private void expandArtists() { - artistAdapter.clear(); - for (Artist artist : searchResult.getArtists()) { - artistAdapter.add(artist); - } - artistAdapter.notifyDataSetChanged(); - mergeAdapter.removeAdapter(moreArtistsAdapter); - mergeAdapter.notifyDataSetChanged(); - } - - private void expandAlbums() { - albumAdapter.clear(); - for (MusicDirectory.Entry album : searchResult.getAlbums()) { - albumAdapter.add(album); - } - albumAdapter.notifyDataSetChanged(); - mergeAdapter.removeAdapter(moreAlbumsAdapter); - mergeAdapter.notifyDataSetChanged(); - } - - private void expandSongs() { - songAdapter.clear(); - for (MusicDirectory.Entry song : searchResult.getSongs()) { - songAdapter.add(song); - } - songAdapter.notifyDataSetChanged(); - mergeAdapter.removeAdapter(moreSongsAdapter); - mergeAdapter.notifyDataSetChanged(); - } - private void onArtistSelected(Artist artist, boolean autoplay) { SubsonicFragment fragment = new SelectDirectoryFragment(); Bundle args = new Bundle(); diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectArtistFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectArtistFragment.java index b282cf6f..065d622f 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectArtistFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectArtistFragment.java @@ -11,11 +11,10 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; -import android.widget.ArrayAdapter; import android.widget.LinearLayout; -import android.widget.TextView; + import github.daneren2005.dsub.R; -import github.daneren2005.dsub.adapter.ArtistAdapter2; +import github.daneren2005.dsub.adapter.ArtistAdapter; import github.daneren2005.dsub.adapter.SectionAdapter; import github.daneren2005.dsub.domain.Artist; import github.daneren2005.dsub.domain.Indexes; @@ -25,14 +24,13 @@ import github.daneren2005.dsub.service.MusicService; import github.daneren2005.dsub.util.Constants; import github.daneren2005.dsub.util.ProgressListener; import github.daneren2005.dsub.util.Util; -import github.daneren2005.dsub.adapter.ArtistAdapter; import github.daneren2005.dsub.view.UpdateView; import java.io.Serializable; import java.util.ArrayList; import java.util.List; -public class SelectArtistFragment extends SelectRecyclerFragment implements ArtistAdapter2.OnMusicFolderChanged { +public class SelectArtistFragment extends SelectRecyclerFragment implements ArtistAdapter.OnMusicFolderChanged { private static final String TAG = SelectArtistFragment.class.getSimpleName(); private static final int MENU_GROUP_MUSIC_FOLDER = 10; @@ -163,7 +161,7 @@ public class SelectArtistFragment extends SelectRecyclerFragment impleme @Override public SectionAdapter getAdapter(List objects) { - return new ArtistAdapter2(context, objects, musicFolders, this, this); + return new ArtistAdapter(context, objects, musicFolders, this, this); } @Override @@ -222,7 +220,7 @@ public class SelectArtistFragment extends SelectRecyclerFragment impleme if(empty && !Util.isOffline(context)) { objects.clear(); - recyclerView.setAdapter(new ArtistAdapter2(context, objects, this)); + recyclerView.setAdapter(new ArtistAdapter(context, objects, this)); recyclerView.setVisibility(View.VISIBLE); View view = rootView.findViewById(R.id.tab_progress); diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectRecyclerFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectRecyclerFragment.java index bd4d9526..526a4312 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectRecyclerFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectRecyclerFragment.java @@ -17,8 +17,6 @@ package github.daneren2005.dsub.fragments; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.GridLayoutManager; -import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; @@ -40,7 +38,6 @@ import github.daneren2005.dsub.util.BackgroundTask; import github.daneren2005.dsub.util.Constants; import github.daneren2005.dsub.util.ProgressListener; import github.daneren2005.dsub.util.TabBackgroundTask; -import github.daneren2005.dsub.view.GridSpacingDecoration; public abstract class SelectRecyclerFragment extends SubsonicFragment implements SectionAdapter.OnItemClickedListener { private static final String TAG = SelectRecyclerFragment.class.getSimpleName(); @@ -49,7 +46,7 @@ public abstract class SelectRecyclerFragment extends SubsonicFragment impleme protected BackgroundTask> currentTask; protected List objects; protected boolean serialize = true; - protected boolean largeCells = false; + protected boolean largeAlbums = false; protected int columns; protected boolean pullToRefresh = true; @@ -158,39 +155,7 @@ public abstract class SelectRecyclerFragment extends SubsonicFragment impleme } private void setupLayoutManager() { - recyclerView.setLayoutManager(getLayoutManager()); - } - public RecyclerView.LayoutManager getLayoutManager() { - if(largeCells) { - return getGridLayoutManager(); - } else { - return getLinearLayoutManager(); - } - } - public GridLayoutManager getGridLayoutManager() { - final int columns = context.getResources().getInteger(R.integer.Grid_Columns); - GridLayoutManager gridLayoutManager = new GridLayoutManager(context, columns); - - GridLayoutManager.SpanSizeLookup spanSizeLookup = getSpanSizeLookup(); - if(spanSizeLookup != null) { - gridLayoutManager.setSpanSizeLookup(spanSizeLookup); - } - RecyclerView.ItemDecoration itemDecoration = getItemDecoration(); - if(itemDecoration != null) { - recyclerView.addItemDecoration(itemDecoration); - } - return gridLayoutManager; - } - public LinearLayoutManager getLinearLayoutManager() { - LinearLayoutManager layoutManager = new LinearLayoutManager(context); - layoutManager.setOrientation(LinearLayoutManager.VERTICAL); - return layoutManager; - } - public GridLayoutManager.SpanSizeLookup getSpanSizeLookup() { - return null; - } - public RecyclerView.ItemDecoration getItemDecoration() { - return new GridSpacingDecoration(); + setupLayoutManager(recyclerView, largeAlbums); } public abstract int getOptionsMenu(); diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SimilarArtistFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SimilarArtistFragment.java index 6284dcb9..088b6d00 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SimilarArtistFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SimilarArtistFragment.java @@ -24,7 +24,7 @@ import android.view.View; import android.widget.AdapterView; import github.daneren2005.dsub.R; -import github.daneren2005.dsub.adapter.ArtistAdapter2; +import github.daneren2005.dsub.adapter.ArtistAdapter; import github.daneren2005.dsub.adapter.SectionAdapter; import github.daneren2005.dsub.domain.Artist; import github.daneren2005.dsub.domain.ArtistInfo; @@ -124,7 +124,7 @@ public class SimilarArtistFragment extends SelectRecyclerFragment { @Override public SectionAdapter getAdapter(List objects) { - return new ArtistAdapter2(context, objects, this); + return new ArtistAdapter(context, objects, this); } @Override diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java index 82d5d97f..cc9f8d62 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java @@ -34,6 +34,8 @@ import android.os.Bundle; import android.os.StatFs; import android.support.v4.app.Fragment; import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.ContextMenu; @@ -81,6 +83,7 @@ import github.daneren2005.dsub.util.Util; import github.daneren2005.dsub.view.AlbumView; import github.daneren2005.dsub.view.ArtistEntryView; import github.daneren2005.dsub.view.ArtistView; +import github.daneren2005.dsub.view.GridSpacingDecoration; import github.daneren2005.dsub.view.PlaylistSongView; import github.daneren2005.dsub.view.SongView; import github.daneren2005.dsub.view.UpdateView; @@ -653,6 +656,45 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR } } + public void setupLayoutManager(RecyclerView recyclerView, boolean largeAlbums) { + recyclerView.setLayoutManager(getLayoutManager(recyclerView, largeAlbums)); + } + public RecyclerView.LayoutManager getLayoutManager(RecyclerView recyclerView, boolean largeCells) { + if(largeCells) { + return getGridLayoutManager(recyclerView); + } else { + return getLinearLayoutManager(); + } + } + public GridLayoutManager getGridLayoutManager(RecyclerView recyclerView) { + final int columns = getRecyclerColumnCount(); + GridLayoutManager gridLayoutManager = new GridLayoutManager(context, columns); + + GridLayoutManager.SpanSizeLookup spanSizeLookup = getSpanSizeLookup(); + if(spanSizeLookup != null) { + gridLayoutManager.setSpanSizeLookup(spanSizeLookup); + } + RecyclerView.ItemDecoration itemDecoration = getItemDecoration(); + if(itemDecoration != null) { + recyclerView.addItemDecoration(itemDecoration); + } + return gridLayoutManager; + } + public LinearLayoutManager getLinearLayoutManager() { + LinearLayoutManager layoutManager = new LinearLayoutManager(context); + layoutManager.setOrientation(LinearLayoutManager.VERTICAL); + return layoutManager; + } + public GridLayoutManager.SpanSizeLookup getSpanSizeLookup() { + return null; + } + public RecyclerView.ItemDecoration getItemDecoration() { + return new GridSpacingDecoration(); + } + public int getRecyclerColumnCount() { + return context.getResources().getInteger(R.integer.Grid_Columns); + } + protected void warnIfStorageUnavailable() { if (!Util.isExternalStoragePresent()) { Util.toast(context, R.string.select_album_no_sdcard); diff --git a/app/src/main/res/layout/basic_header.xml b/app/src/main/res/layout/basic_header.xml index 39f8722d..b5ae900a 100644 --- a/app/src/main/res/layout/basic_header.xml +++ b/app/src/main/res/layout/basic_header.xml @@ -8,4 +8,6 @@ android:textColor="@color/cyan" android:textStyle="bold" android:paddingLeft="6dp" - android:paddingRight="6dp"/> \ No newline at end of file + android:paddingRight="6dp" + android:paddingTop="8dp" + android:paddingBottom="8dp"/> \ No newline at end of file -- cgit v1.2.3