mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
Search page renewed
This commit is contained in:
parent
a4dc5f643d
commit
a7fd7688ab
13 changed files with 358 additions and 174 deletions
|
|
@ -17,6 +17,7 @@ import com.cappielloantonio.play.model.Album;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder> {
|
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder> {
|
||||||
private static final String TAG = "AlbumAdapter";
|
private static final String TAG = "AlbumAdapter";
|
||||||
|
|
@ -75,8 +76,17 @@ public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder>
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition()));
|
bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition()));
|
||||||
|
|
||||||
|
if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.searchFragment) {
|
||||||
|
Navigation.findNavController(view).navigate(R.id.action_searchFragment_to_albumPageFragment, bundle);
|
||||||
|
}
|
||||||
|
else if(Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) {
|
||||||
Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_albumPageFragment, bundle);
|
Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_albumPageFragment, bundle);
|
||||||
}
|
}
|
||||||
|
else if(Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.albumCatalogueFragment) {
|
||||||
|
Navigation.findNavController(view).navigate(R.id.action_albumCatalogueFragment_to_albumPageFragment, bundle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onLongClick(View v) {
|
public boolean onLongClick(View v) {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import com.cappielloantonio.play.model.Artist;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ViewHolder> {
|
public class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ViewHolder> {
|
||||||
private static final String TAG = "ArtistAdapter";
|
private static final String TAG = "ArtistAdapter";
|
||||||
|
|
@ -72,8 +73,17 @@ public class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ViewHolder
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition()));
|
bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition()));
|
||||||
|
|
||||||
|
if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.searchFragment) {
|
||||||
|
Navigation.findNavController(view).navigate(R.id.action_searchFragment_to_artistPageFragment, bundle);
|
||||||
|
}
|
||||||
|
else if(Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) {
|
||||||
Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_artistPageFragment, bundle);
|
Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_artistPageFragment, bundle);
|
||||||
}
|
}
|
||||||
|
else if(Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.artistCatalogueFragment) {
|
||||||
|
Navigation.findNavController(view).navigate(R.id.action_artistCatalogueFragment_to_artistPageFragment, bundle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onLongClick(View v) {
|
public boolean onLongClick(View v) {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import com.cappielloantonio.play.model.Song;
|
||||||
import com.cappielloantonio.play.model.SongArtistCross;
|
import com.cappielloantonio.play.model.SongArtistCross;
|
||||||
import com.cappielloantonio.play.model.SongGenreCross;
|
import com.cappielloantonio.play.model.SongGenreCross;
|
||||||
|
|
||||||
@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class, Queue.class, AlbumArtistCross.class, SongArtistCross.class, PlaylistSongCross.class}, version = 10, exportSchema = false)
|
@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class, Queue.class, AlbumArtistCross.class, SongArtistCross.class, PlaylistSongCross.class}, version = 11, exportSchema = false)
|
||||||
public abstract class AppDatabase extends RoomDatabase {
|
public abstract class AppDatabase extends RoomDatabase {
|
||||||
private static final String TAG = "AppDatabase";
|
private static final String TAG = "AppDatabase";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import androidx.room.Insert;
|
||||||
import androidx.room.OnConflictStrategy;
|
import androidx.room.OnConflictStrategy;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
|
|
||||||
|
import com.cappielloantonio.play.model.Artist;
|
||||||
import com.cappielloantonio.play.model.Genre;
|
import com.cappielloantonio.play.model.Genre;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -27,4 +28,10 @@ public interface GenreDao {
|
||||||
|
|
||||||
@Query("DELETE FROM genre")
|
@Query("DELETE FROM genre")
|
||||||
void deleteAll();
|
void deleteAll();
|
||||||
|
|
||||||
|
@Query("SELECT * FROM genre WHERE name LIKE '%' || :name || '%'")
|
||||||
|
LiveData<List<Genre>> searchGenre(String name);
|
||||||
|
|
||||||
|
@Query("SELECT name FROM genre WHERE name LIKE :query || '%' OR name like '% ' || :query || '%' GROUP BY name LIMIT :number")
|
||||||
|
List<String> searchSuggestions(String query, int number);
|
||||||
}
|
}
|
||||||
|
|
@ -13,12 +13,15 @@ import java.util.List;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public interface RecentSearchDao {
|
public interface RecentSearchDao {
|
||||||
@Query("SELECT * FROM recent_search GROUP BY search ORDER BY id DESC LIMIT :limit")
|
@Query("SELECT * FROM recent_search GROUP BY search ORDER BY search DESC LIMIT :limit")
|
||||||
LiveData<List<RecentSearch>> getLast(int limit);
|
List<String> getRecent(int limit);
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
void insert(RecentSearch search);
|
void insert(RecentSearch search);
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
void delete(RecentSearch search);
|
||||||
|
|
||||||
@Query("DELETE FROM recent_search")
|
@Query("DELETE FROM recent_search")
|
||||||
void deleteAll();
|
void deleteAll();
|
||||||
}
|
}
|
||||||
|
|
@ -8,10 +8,7 @@ import androidx.room.PrimaryKey;
|
||||||
@Entity(tableName = "recent_search")
|
@Entity(tableName = "recent_search")
|
||||||
public class RecentSearch {
|
public class RecentSearch {
|
||||||
@NonNull
|
@NonNull
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey
|
||||||
@ColumnInfo(name = "id")
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
@ColumnInfo(name = "search")
|
@ColumnInfo(name = "search")
|
||||||
private String search;
|
private String search;
|
||||||
|
|
||||||
|
|
@ -20,14 +17,6 @@ public class RecentSearch {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(@NonNull int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSearch() {
|
public String getSearch() {
|
||||||
return search;
|
return search;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@ import android.app.Application;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
|
|
||||||
import com.cappielloantonio.play.database.AppDatabase;
|
import com.cappielloantonio.play.database.AppDatabase;
|
||||||
|
import com.cappielloantonio.play.database.dao.ArtistDao;
|
||||||
import com.cappielloantonio.play.database.dao.GenreDao;
|
import com.cappielloantonio.play.database.dao.GenreDao;
|
||||||
import com.cappielloantonio.play.database.dao.SongGenreCrossDao;
|
import com.cappielloantonio.play.database.dao.SongGenreCrossDao;
|
||||||
|
import com.cappielloantonio.play.model.Artist;
|
||||||
import com.cappielloantonio.play.model.Genre;
|
import com.cappielloantonio.play.model.Genre;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -17,6 +19,7 @@ public class GenreRepository {
|
||||||
private SongGenreCrossDao songGenreCrossDao;
|
private SongGenreCrossDao songGenreCrossDao;
|
||||||
private LiveData<List<Genre>> listLiveGenres;
|
private LiveData<List<Genre>> listLiveGenres;
|
||||||
private LiveData<List<Genre>> listLiveAlbumGenre;
|
private LiveData<List<Genre>> listLiveAlbumGenre;
|
||||||
|
private LiveData<List<Genre>> searchListLiveGenre;
|
||||||
|
|
||||||
public GenreRepository(Application application) {
|
public GenreRepository(Application application) {
|
||||||
AppDatabase database = AppDatabase.getInstance(application);
|
AppDatabase database = AppDatabase.getInstance(application);
|
||||||
|
|
@ -110,4 +113,48 @@ public class GenreRepository {
|
||||||
genreDao.deleteAll();
|
genreDao.deleteAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Genre>> searchListLiveGenre(String name) {
|
||||||
|
searchListLiveGenre = genreDao.searchGenre(name);
|
||||||
|
return searchListLiveGenre;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSearchSuggestion(String query) {
|
||||||
|
List<String> suggestions = new ArrayList<>();
|
||||||
|
|
||||||
|
SearchSuggestionsThreadSafe suggestionsThread = new SearchSuggestionsThreadSafe(genreDao, query, 5);
|
||||||
|
Thread thread = new Thread(suggestionsThread);
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
try {
|
||||||
|
thread.join();
|
||||||
|
suggestions = suggestionsThread.getSuggestions();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SearchSuggestionsThreadSafe implements Runnable {
|
||||||
|
private GenreDao genreDao;
|
||||||
|
private String query;
|
||||||
|
private int number;
|
||||||
|
private List<String> suggestions = new ArrayList<>();
|
||||||
|
|
||||||
|
public SearchSuggestionsThreadSafe(GenreDao genreDao, String query, int number) {
|
||||||
|
this.genreDao = genreDao;
|
||||||
|
this.query = query;
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
suggestions = genreDao.searchSuggestions(query, number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSuggestions() {
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,20 +8,15 @@ import com.cappielloantonio.play.database.AppDatabase;
|
||||||
import com.cappielloantonio.play.database.dao.RecentSearchDao;
|
import com.cappielloantonio.play.database.dao.RecentSearchDao;
|
||||||
import com.cappielloantonio.play.model.RecentSearch;
|
import com.cappielloantonio.play.model.RecentSearch;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class RecentSearchRepository {
|
public class RecentSearchRepository {
|
||||||
private RecentSearchDao recentSearchDao;
|
private RecentSearchDao recentSearchDao;
|
||||||
private LiveData<List<RecentSearch>> listLiveRecentSearches;
|
|
||||||
|
|
||||||
public RecentSearchRepository(Application application) {
|
public RecentSearchRepository(Application application) {
|
||||||
AppDatabase database = AppDatabase.getInstance(application);
|
AppDatabase database = AppDatabase.getInstance(application);
|
||||||
recentSearchDao = database.recentSearchDao();
|
recentSearchDao = database.recentSearchDao();
|
||||||
listLiveRecentSearches = recentSearchDao.getLast(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<List<RecentSearch>> getListLiveRecentSearches() {
|
|
||||||
return listLiveRecentSearches;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert(RecentSearch recentSearch) {
|
public void insert(RecentSearch recentSearch) {
|
||||||
|
|
@ -30,6 +25,27 @@ public class RecentSearchRepository {
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void delete(RecentSearch recentSearch) {
|
||||||
|
DeleteThreadSafe delete = new DeleteThreadSafe(recentSearchDao, recentSearch);
|
||||||
|
Thread thread = new Thread(delete);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DeleteThreadSafe implements Runnable {
|
||||||
|
private RecentSearchDao recentSearchDao;
|
||||||
|
private RecentSearch recentSearch;
|
||||||
|
|
||||||
|
public DeleteThreadSafe(RecentSearchDao recentSearchDao, RecentSearch recentSearch) {
|
||||||
|
this.recentSearchDao = recentSearchDao;
|
||||||
|
this.recentSearch = recentSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
recentSearchDao.delete(recentSearch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class InsertThreadSafe implements Runnable {
|
private static class InsertThreadSafe implements Runnable {
|
||||||
private RecentSearchDao recentSearchDao;
|
private RecentSearchDao recentSearchDao;
|
||||||
private RecentSearch recentSearch;
|
private RecentSearch recentSearch;
|
||||||
|
|
@ -63,4 +79,41 @@ public class RecentSearchRepository {
|
||||||
recentSearchDao.deleteAll();
|
recentSearchDao.deleteAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getRecentSearchSuggestion() {
|
||||||
|
List<String> recent = new ArrayList<>();
|
||||||
|
|
||||||
|
RecentThreadSafe suggestionsThread = new RecentThreadSafe(recentSearchDao,10);
|
||||||
|
Thread thread = new Thread(suggestionsThread);
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
try {
|
||||||
|
thread.join();
|
||||||
|
recent = suggestionsThread.getRecent();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return recent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RecentThreadSafe implements Runnable {
|
||||||
|
private RecentSearchDao recentSearchDao;
|
||||||
|
private int limit;
|
||||||
|
private List<String> recent = new ArrayList<>();
|
||||||
|
|
||||||
|
public RecentThreadSafe(RecentSearchDao recentSearchDao, int limit) {
|
||||||
|
this.recentSearchDao = recentSearchDao;
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
recent = recentSearchDao.getRecent(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getRecent() {
|
||||||
|
return recent;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,18 @@ import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
|
import com.cappielloantonio.play.R;
|
||||||
|
import com.cappielloantonio.play.adapter.AlbumAdapter;
|
||||||
import com.cappielloantonio.play.adapter.AlbumCatalogueAdapter;
|
import com.cappielloantonio.play.adapter.AlbumCatalogueAdapter;
|
||||||
|
import com.cappielloantonio.play.adapter.ArtistAdapter;
|
||||||
import com.cappielloantonio.play.adapter.ArtistCatalogueAdapter;
|
import com.cappielloantonio.play.adapter.ArtistCatalogueAdapter;
|
||||||
|
import com.cappielloantonio.play.adapter.GenreCatalogueAdapter;
|
||||||
import com.cappielloantonio.play.adapter.RecentSearchAdapter;
|
import com.cappielloantonio.play.adapter.RecentSearchAdapter;
|
||||||
import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
|
import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
|
||||||
import com.cappielloantonio.play.databinding.FragmentSearchBinding;
|
import com.cappielloantonio.play.databinding.FragmentSearchBinding;
|
||||||
import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration;
|
import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration;
|
||||||
import com.cappielloantonio.play.model.RecentSearch;
|
import com.cappielloantonio.play.model.RecentSearch;
|
||||||
|
import com.cappielloantonio.play.model.Song;
|
||||||
import com.cappielloantonio.play.ui.activities.MainActivity;
|
import com.cappielloantonio.play.ui.activities.MainActivity;
|
||||||
import com.cappielloantonio.play.viewmodel.SearchViewModel;
|
import com.cappielloantonio.play.viewmodel.SearchViewModel;
|
||||||
import com.paulrybitskyi.persistentsearchview.adapters.model.SuggestionItem;
|
import com.paulrybitskyi.persistentsearchview.adapters.model.SuggestionItem;
|
||||||
|
|
@ -35,10 +40,10 @@ public class SearchFragment extends Fragment {
|
||||||
private MainActivity activity;
|
private MainActivity activity;
|
||||||
private SearchViewModel searchViewModel;
|
private SearchViewModel searchViewModel;
|
||||||
|
|
||||||
private RecentSearchAdapter recentSearchAdapter;
|
|
||||||
private SongResultSearchAdapter songResultSearchAdapter;
|
private SongResultSearchAdapter songResultSearchAdapter;
|
||||||
private AlbumCatalogueAdapter albumResultSearchAdapter;
|
private AlbumAdapter albumAdapter;
|
||||||
private ArtistCatalogueAdapter artistResultSearchAdapter;
|
private ArtistAdapter artistAdapter;
|
||||||
|
private GenreCatalogueAdapter genreCatalogueAdapter;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -49,8 +54,6 @@ public class SearchFragment extends Fragment {
|
||||||
View view = bind.getRoot();
|
View view = bind.getRoot();
|
||||||
searchViewModel = new ViewModelProvider(requireActivity()).get(SearchViewModel.class);
|
searchViewModel = new ViewModelProvider(requireActivity()).get(SearchViewModel.class);
|
||||||
|
|
||||||
init();
|
|
||||||
initRecentSearchView();
|
|
||||||
initSearchResultView();
|
initSearchResultView();
|
||||||
initSearchView();
|
initSearchView();
|
||||||
|
|
||||||
|
|
@ -63,30 +66,18 @@ public class SearchFragment extends Fragment {
|
||||||
activity.setBottomNavigationBarVisibility(true);
|
activity.setBottomNavigationBarVisibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
inputFocus();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
bind = null;
|
bind = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
|
||||||
bind.clearAllSearchTextViewClickable.setOnClickListener(v -> searchViewModel.deleteAllRecentSearch());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initRecentSearchView() {
|
|
||||||
bind.recentlySearchedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
|
||||||
bind.recentlySearchedTracksRecyclerView.setHasFixedSize(true);
|
|
||||||
|
|
||||||
recentSearchAdapter = new RecentSearchAdapter(requireContext());
|
|
||||||
recentSearchAdapter.setClickListener((view, position) -> {
|
|
||||||
RecentSearch search = recentSearchAdapter.getItem(position);
|
|
||||||
search(search.getSearch());
|
|
||||||
});
|
|
||||||
bind.recentlySearchedTracksRecyclerView.setAdapter(recentSearchAdapter);
|
|
||||||
|
|
||||||
searchViewModel.getSearchList().observe(requireActivity(), recentSearches -> recentSearchAdapter.setItems(recentSearches));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initSearchResultView() {
|
private void initSearchResultView() {
|
||||||
// Songs
|
// Songs
|
||||||
bind.searchResultTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
bind.searchResultTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||||
|
|
@ -96,28 +87,47 @@ public class SearchFragment extends Fragment {
|
||||||
bind.searchResultTracksRecyclerView.setAdapter(songResultSearchAdapter);
|
bind.searchResultTracksRecyclerView.setAdapter(songResultSearchAdapter);
|
||||||
|
|
||||||
// Albums
|
// Albums
|
||||||
bind.searchResultAlbumRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 2));
|
bind.searchResultAlbumRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||||
bind.searchResultAlbumRecyclerView.addItemDecoration(new GridItemDecoration(2, 20, false));
|
|
||||||
bind.searchResultAlbumRecyclerView.setHasFixedSize(true);
|
bind.searchResultAlbumRecyclerView.setHasFixedSize(true);
|
||||||
|
|
||||||
albumResultSearchAdapter = new AlbumCatalogueAdapter(requireContext());
|
albumAdapter = new AlbumAdapter(requireContext());
|
||||||
bind.searchResultAlbumRecyclerView.setAdapter(albumResultSearchAdapter);
|
bind.searchResultAlbumRecyclerView.setAdapter(albumAdapter);
|
||||||
|
|
||||||
// Artist
|
// Artists
|
||||||
bind.searchResultArtistRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 2));
|
bind.searchResultArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||||
bind.searchResultArtistRecyclerView.addItemDecoration(new GridItemDecoration(2, 20, false));
|
|
||||||
bind.searchResultArtistRecyclerView.setHasFixedSize(true);
|
bind.searchResultArtistRecyclerView.setHasFixedSize(true);
|
||||||
|
|
||||||
artistResultSearchAdapter = new ArtistCatalogueAdapter(requireContext());
|
artistAdapter = new ArtistAdapter(requireContext());
|
||||||
bind.searchResultArtistRecyclerView.setAdapter(artistResultSearchAdapter);
|
bind.searchResultArtistRecyclerView.setAdapter(artistAdapter);
|
||||||
|
|
||||||
|
// Genres
|
||||||
|
bind.searchResultGenreRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 2));
|
||||||
|
bind.searchResultGenreRecyclerView.addItemDecoration(new GridItemDecoration(2, 16, false));
|
||||||
|
bind.searchResultGenreRecyclerView.setHasFixedSize(true);
|
||||||
|
|
||||||
|
genreCatalogueAdapter = new GenreCatalogueAdapter(requireContext());
|
||||||
|
genreCatalogueAdapter.setClickListener((view, position) -> {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString(Song.BY_GENRE, Song.BY_GENRE);
|
||||||
|
bundle.putParcelable("genre_object", genreCatalogueAdapter.getItem(position));
|
||||||
|
activity.navController.navigate(R.id.action_searchFragment_to_songListPageFragment, bundle);
|
||||||
|
});
|
||||||
|
bind.searchResultGenreRecyclerView.setAdapter(genreCatalogueAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSearchView() {
|
private void initSearchView() {
|
||||||
|
if (isQueryValid(searchViewModel.getQuery())) {
|
||||||
|
search(searchViewModel.getQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
bind.persistentSearchView.setInputQuery(searchViewModel.getQuery());
|
||||||
|
setSuggestions();
|
||||||
|
|
||||||
bind.persistentSearchView.setOnSearchQueryChangeListener((searchView, oldQuery, newQuery) -> {
|
bind.persistentSearchView.setOnSearchQueryChangeListener((searchView, oldQuery, newQuery) -> {
|
||||||
if (!newQuery.trim().equals("") && newQuery.trim().length() > 1) {
|
if (!newQuery.trim().equals("") && newQuery.trim().length() > 1) {
|
||||||
searchView.setSuggestions(SuggestionCreationUtil.asRegularSearchSuggestions(searchViewModel.getSearchSuggestion(newQuery)), false);
|
searchView.setSuggestions(SuggestionCreationUtil.asRegularSearchSuggestions(searchViewModel.getSearchSuggestion(newQuery)), false);
|
||||||
} else {
|
} else {
|
||||||
searchView.setSuggestions(new ArrayList<>());
|
setSuggestions();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -133,27 +143,69 @@ public class SearchFragment extends Fragment {
|
||||||
});
|
});
|
||||||
|
|
||||||
bind.persistentSearchView.setOnSearchConfirmedListener((searchView, query) -> {
|
bind.persistentSearchView.setOnSearchConfirmedListener((searchView, query) -> {
|
||||||
|
if (isQueryValid(query)) {
|
||||||
|
searchView.collapse();
|
||||||
search(query);
|
search(query);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Toast.makeText(requireContext(), "Enter at least three characters", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bind.persistentSearchView.setOnSuggestionChangeListener(new OnSuggestionChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onSuggestionPicked(SuggestionItem suggestion) {
|
||||||
|
search(suggestion.getItemModel().getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuggestionRemoved(SuggestionItem suggestion) {
|
||||||
|
searchViewModel.deleteRecentSearch(suggestion.getItemModel().getText());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bind.persistentSearchView.setOnClearInputBtnClickListener(v -> searchViewModel.setQuery(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSuggestions() {
|
||||||
|
bind.persistentSearchView.setSuggestions(SuggestionCreationUtil.asRecentSearchSuggestions(searchViewModel.getRecentSearchSuggestion()), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void search(String query) {
|
public void search(String query) {
|
||||||
if (!query.trim().equals("") && query.trim().length() > 2) {
|
searchViewModel.setQuery(query);
|
||||||
searchViewModel.insertNewSearch(query);
|
|
||||||
bind.persistentSearchView.collapse();
|
|
||||||
|
|
||||||
bind.persistentSearchView.setInputQuery(query);
|
bind.persistentSearchView.setInputQuery(query);
|
||||||
performSearch(query.trim());
|
performSearch(query);
|
||||||
} else {
|
|
||||||
Toast.makeText(requireContext(), "Enter at least three characters", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performSearch(String query) {
|
private void performSearch(String query) {
|
||||||
searchViewModel.searchSong(query).observe(requireActivity(), songs -> songResultSearchAdapter.setItems(songs));
|
searchViewModel.searchSong(query).observe(requireActivity(), songs -> {
|
||||||
searchViewModel.searchAlbum(query).observe(requireActivity(), albums -> albumResultSearchAdapter.setItems(albums));
|
if(bind != null) bind.searchSongSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
searchViewModel.searchArtist(query).observe(requireActivity(), artists -> artistResultSearchAdapter.setItems(artists));
|
songResultSearchAdapter.setItems(songs);
|
||||||
|
});
|
||||||
|
searchViewModel.searchAlbum(query).observe(requireActivity(), albums -> {
|
||||||
|
if(bind != null) bind.searchAlbumSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
|
albumAdapter.setItems(albums);
|
||||||
|
});
|
||||||
|
searchViewModel.searchArtist(query).observe(requireActivity(), artists -> {
|
||||||
|
if(bind != null) bind.searchArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
|
artistAdapter.setItems(artists);
|
||||||
|
});
|
||||||
|
searchViewModel.searchGenre(query).observe(requireActivity(), genres -> {
|
||||||
|
if(bind != null) bind.searchGenreSector.setVisibility(!genres.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
|
genreCatalogueAdapter.setItems(genres);
|
||||||
|
});
|
||||||
|
|
||||||
bind.searchResultLayout.setVisibility(View.VISIBLE);
|
bind.searchResultLayout.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isQueryValid(String query) {
|
||||||
|
return !query.equals("") && query.trim().length() > 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inputFocus() {
|
||||||
|
if(!isQueryValid(searchViewModel.getQuery())) {
|
||||||
|
bind.persistentSearchView.expand();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@ import androidx.lifecycle.LiveData;
|
||||||
|
|
||||||
import com.cappielloantonio.play.model.Album;
|
import com.cappielloantonio.play.model.Album;
|
||||||
import com.cappielloantonio.play.model.Artist;
|
import com.cappielloantonio.play.model.Artist;
|
||||||
|
import com.cappielloantonio.play.model.Genre;
|
||||||
import com.cappielloantonio.play.model.RecentSearch;
|
import com.cappielloantonio.play.model.RecentSearch;
|
||||||
import com.cappielloantonio.play.model.Song;
|
import com.cappielloantonio.play.model.Song;
|
||||||
import com.cappielloantonio.play.repository.AlbumRepository;
|
import com.cappielloantonio.play.repository.AlbumRepository;
|
||||||
import com.cappielloantonio.play.repository.ArtistRepository;
|
import com.cappielloantonio.play.repository.ArtistRepository;
|
||||||
|
import com.cappielloantonio.play.repository.GenreRepository;
|
||||||
import com.cappielloantonio.play.repository.RecentSearchRepository;
|
import com.cappielloantonio.play.repository.RecentSearchRepository;
|
||||||
import com.cappielloantonio.play.repository.SongRepository;
|
import com.cappielloantonio.play.repository.SongRepository;
|
||||||
|
|
||||||
|
|
@ -22,15 +24,18 @@ import java.util.List;
|
||||||
public class SearchViewModel extends AndroidViewModel {
|
public class SearchViewModel extends AndroidViewModel {
|
||||||
private static final String TAG = "SearchViewModel";
|
private static final String TAG = "SearchViewModel";
|
||||||
|
|
||||||
|
private String query = "";
|
||||||
|
|
||||||
private SongRepository songRepository;
|
private SongRepository songRepository;
|
||||||
private AlbumRepository albumRepository;
|
private AlbumRepository albumRepository;
|
||||||
private ArtistRepository artistRepository;
|
private ArtistRepository artistRepository;
|
||||||
|
private GenreRepository genreRepository;
|
||||||
private RecentSearchRepository recentSearchRepository;
|
private RecentSearchRepository recentSearchRepository;
|
||||||
|
|
||||||
private LiveData<List<Song>> searchSong;
|
private LiveData<List<Song>> searchSong;
|
||||||
private LiveData<List<Album>> searchAlbum;
|
private LiveData<List<Album>> searchAlbum;
|
||||||
private LiveData<List<Artist>> searchArtist;
|
private LiveData<List<Artist>> searchArtist;
|
||||||
private LiveData<List<RecentSearch>> recentSearches;
|
private LiveData<List<Genre>> searchGenre;
|
||||||
|
|
||||||
public SearchViewModel(@NonNull Application application) {
|
public SearchViewModel(@NonNull Application application) {
|
||||||
super(application);
|
super(application);
|
||||||
|
|
@ -38,9 +43,22 @@ public class SearchViewModel extends AndroidViewModel {
|
||||||
songRepository = new SongRepository(application);
|
songRepository = new SongRepository(application);
|
||||||
albumRepository = new AlbumRepository(application);
|
albumRepository = new AlbumRepository(application);
|
||||||
artistRepository = new ArtistRepository(application);
|
artistRepository = new ArtistRepository(application);
|
||||||
|
genreRepository = new GenreRepository(application);
|
||||||
recentSearchRepository = new RecentSearchRepository(application);
|
recentSearchRepository = new RecentSearchRepository(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getQuery() {
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuery(String query) {
|
||||||
|
this.query = query;
|
||||||
|
|
||||||
|
if(!query.isEmpty()) {
|
||||||
|
insertNewSearch(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public LiveData<List<Song>> searchSong(String title) {
|
public LiveData<List<Song>> searchSong(String title) {
|
||||||
searchSong = songRepository.searchListLiveSong(title);
|
searchSong = songRepository.searchListLiveSong(title);
|
||||||
return searchSong;
|
return searchSong;
|
||||||
|
|
@ -56,17 +74,17 @@ public class SearchViewModel extends AndroidViewModel {
|
||||||
return searchArtist;
|
return searchArtist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<RecentSearch>> getSearchList() {
|
public LiveData<List<Genre>> searchGenre(String name) {
|
||||||
recentSearches = recentSearchRepository.getListLiveRecentSearches();
|
searchGenre = genreRepository.searchListLiveGenre(name);
|
||||||
return recentSearches;
|
return searchGenre;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertNewSearch(String search) {
|
public void insertNewSearch(String search) {
|
||||||
recentSearchRepository.insert(new RecentSearch(search));
|
recentSearchRepository.insert(new RecentSearch(search));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAllRecentSearch() {
|
public void deleteRecentSearch(String search) {
|
||||||
recentSearchRepository.deleteAll();
|
recentSearchRepository.delete(new RecentSearch(search));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getSearchSuggestion(String query) {
|
public List<String> getSearchSuggestion(String query) {
|
||||||
|
|
@ -74,10 +92,18 @@ public class SearchViewModel extends AndroidViewModel {
|
||||||
suggestions.addAll(songRepository.getSearchSuggestion(query));
|
suggestions.addAll(songRepository.getSearchSuggestion(query));
|
||||||
suggestions.addAll(albumRepository.getSearchSuggestion(query));
|
suggestions.addAll(albumRepository.getSearchSuggestion(query));
|
||||||
suggestions.addAll(artistRepository.getSearchSuggestion(query));
|
suggestions.addAll(artistRepository.getSearchSuggestion(query));
|
||||||
|
suggestions.addAll(genreRepository.getSearchSuggestion(query));
|
||||||
|
|
||||||
LinkedHashSet<String> hashSet = new LinkedHashSet<>(suggestions);
|
LinkedHashSet<String> hashSet = new LinkedHashSet<>(suggestions);
|
||||||
ArrayList<String> suggestionsWithoutDuplicates = new ArrayList<>(hashSet);
|
ArrayList<String> suggestionsWithoutDuplicates = new ArrayList<>(hashSet);
|
||||||
|
|
||||||
return suggestionsWithoutDuplicates;
|
return suggestionsWithoutDuplicates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getRecentSearchSuggestion() {
|
||||||
|
ArrayList<String> suggestions = new ArrayList<>();
|
||||||
|
suggestions.addAll(recentSearchRepository.getRecentSearchSuggestion());
|
||||||
|
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,65 +42,6 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/persistentSearchView" >
|
android:layout_below="@id/persistentSearchView" >
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<!-- Recent searched -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<!-- Label and button -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:paddingEnd="8dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:fontFamily="@font/open_sans_font_family"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingTop="12dp"
|
|
||||||
android:paddingBottom="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:text="Recent Searches"
|
|
||||||
android:textColor="@color/titleTextColor"
|
|
||||||
android:textSize="22sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/clear_all_search_text_view_clickable"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fontFamily="@font/open_sans_font_family"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingTop="12dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:text="Clear all"
|
|
||||||
android:textColor="@color/subtitleTextColor"
|
|
||||||
android:textSize="14sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/recently_searched_tracks_recycler_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:nestedScrollingEnabled="false"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Search result -->
|
<!-- Search result -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/search_result_layout"
|
android:id="@+id/search_result_layout"
|
||||||
|
|
@ -110,91 +51,134 @@
|
||||||
android:paddingBottom="@dimen/global_padding_bottom"
|
android:paddingBottom="@dimen/global_padding_bottom"
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<!-- Label -->
|
<!-- Songs -->
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/search_song_sector"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/open_sans_font_family"
|
android:orientation="vertical"
|
||||||
android:paddingStart="16dp"
|
android:paddingBottom="8dp">
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:text="Search results"
|
|
||||||
android:textColor="@color/titleTextColor"
|
|
||||||
android:textSize="22sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/open_sans_font_family"
|
android:fontFamily="@font/open_sans_font_family"
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="20dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingEnd="16dp"
|
||||||
android:text="Songs"
|
android:text="Songs"
|
||||||
android:textColor="@color/titleTextColor"
|
android:textColor="@color/titleTextColor"
|
||||||
android:textSize="18sp"
|
android:textSize="22sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/search_result_tracks_recycler_view"
|
android:id="@+id/search_result_tracks_recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:overScrollMode="never"
|
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingBottom="24dp"
|
android:paddingBottom="8dp" />
|
||||||
android:nestedScrollingEnabled="false"/>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Album -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/search_album_sector"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/open_sans_font_family"
|
android:fontFamily="@font/open_sans_font_family"
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="20dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingEnd="16dp"
|
||||||
android:text="Albums"
|
android:text="Albums"
|
||||||
android:textColor="@color/titleTextColor"
|
android:textColor="@color/titleTextColor"
|
||||||
android:textSize="18sp"
|
android:textSize="22sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/search_result_album_recycler_view"
|
android:id="@+id/search_result_album_recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:overScrollMode="never"
|
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="8dp" />
|
||||||
android:nestedScrollingEnabled="false"/>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Artist -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/search_artist_sector"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/open_sans_font_family"
|
android:fontFamily="@font/open_sans_font_family"
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingTop="20dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingEnd="16dp"
|
||||||
android:text="Artists"
|
android:text="Artists"
|
||||||
android:textColor="@color/titleTextColor"
|
android:textColor="@color/titleTextColor"
|
||||||
android:textSize="18sp"
|
android:textSize="22sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/search_result_artist_recycler_view"
|
android:id="@+id/search_result_artist_recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:overScrollMode="never"
|
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:paddingBottom="56dp"
|
android:paddingBottom="8dp" />
|
||||||
android:nestedScrollingEnabled="false"/>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Genre -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/search_genre_sector"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/open_sans_font_family"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:text="Genres"
|
||||||
|
android:textColor="@color/titleTextColor"
|
||||||
|
android:textSize="22sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/search_result_genre_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingBottom="8dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
android:id="@+id/genre_label"
|
android:id="@+id/genre_label"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
android:gravity="center_vertical"
|
||||||
android:fontFamily="@font/open_sans_font_family"
|
android:fontFamily="@font/open_sans_font_family"
|
||||||
android:paddingStart="8dp"
|
android:paddingStart="8dp"
|
||||||
android:text="@string/label_placeholder"
|
android:text="@string/label_placeholder"
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,9 @@
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_searchFragment_to_albumPageFragment"
|
android:id="@+id/action_searchFragment_to_albumPageFragment"
|
||||||
app:destination="@id/albumPageFragment" />
|
app:destination="@id/albumPageFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_searchFragment_to_songListPageFragment"
|
||||||
|
app:destination="@id/songListPageFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/filterFragment"
|
android:id="@+id/filterFragment"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue