mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
Add experimental bottom sheet player
This commit is contained in:
parent
9af0afa441
commit
f837bb14e2
65 changed files with 1570 additions and 547 deletions
|
|
@ -36,6 +36,7 @@ android {
|
|||
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
|
||||
// Jellyfin
|
||||
implementation 'com.github.jellyfin.jellyfin-apiclient-java:android:0.7.7'
|
||||
|
||||
|
|
@ -48,13 +49,14 @@ dependencies {
|
|||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
||||
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation "androidx.room:room-runtime:2.2.5"
|
||||
implementation "androidx.cardview:cardview:1.0.0"
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.paging:paging-runtime:2.1.2'
|
||||
implementation 'androidx.paging:paging-runtime-ktx:2.1.2'
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
|
||||
|
||||
// Android Material
|
||||
implementation 'com.google.android.material:material:1.2.1'
|
||||
|
|
@ -72,7 +74,7 @@ dependencies {
|
|||
// Glide
|
||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||
implementation "com.github.woltapp:blurhash:f41a23cc50"
|
||||
|
||||
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
|
||||
annotationProcessor "androidx.room:room-compiler:2.2.5"
|
||||
testImplementation 'junit:junit:4.13.1'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
package com.cappielloantonio.play.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.cappielloantonio.play.App;
|
||||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.repository.SongRepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerNowPlayingSongAdapter extends RecyclerView.Adapter<PlayerNowPlayingSongAdapter.ViewHolder> {
|
||||
private static final String TAG = "DiscoverSongAdapter";
|
||||
|
||||
private List<Song> songs;
|
||||
private LayoutInflater inflater;
|
||||
private Context context;
|
||||
|
||||
public PlayerNowPlayingSongAdapter(Context context) {
|
||||
this.context = context;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.songs = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = inflater.inflate(R.layout.item_player_now_playing_song, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
Song song = songs.get(position);
|
||||
|
||||
CustomGlideRequest.Builder
|
||||
.from(context, song.getPrimary(), song.getPrimary(), CustomGlideRequest.PRIMARY, CustomGlideRequest.TOP_QUALITY)
|
||||
.build()
|
||||
.into(holder.cover);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return songs.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
ImageView cover;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
cover = itemView.findViewById(R.id.discover_song_cover_image_view);
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
SongRepository songRepository = new SongRepository(App.getInstance());
|
||||
songRepository.increasePlayCount(songs.get(getAdapterPosition()));
|
||||
}
|
||||
}
|
||||
|
||||
public void setItems(List<Song> songs) {
|
||||
this.songs = songs;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
package com.cappielloantonio.play.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.cappielloantonio.play.App;
|
||||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.repository.QueueRepository;
|
||||
import com.cappielloantonio.play.repository.SongRepository;
|
||||
import com.cappielloantonio.play.ui.activities.MainActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Adapter per i brani ritrovati nella ricerca
|
||||
*/
|
||||
public class PlayerSongQueueAdapter extends RecyclerView.Adapter<PlayerSongQueueAdapter.ViewHolder> {
|
||||
private static final String TAG = "SongResultSearchAdapter";
|
||||
|
||||
private List<Song> songs;
|
||||
private LayoutInflater mInflater;
|
||||
private MainActivity mainActivity;
|
||||
private Context context;
|
||||
private FragmentManager fragmentManager;
|
||||
|
||||
public PlayerSongQueueAdapter(MainActivity mainActivity, Context context, FragmentManager fragmentManager) {
|
||||
this.mainActivity = mainActivity;
|
||||
this.context = context;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.mInflater = LayoutInflater.from(context);
|
||||
this.songs = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = mInflater.inflate(R.layout.item_player_queue_song, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
Song song = songs.get(position);
|
||||
|
||||
holder.songTitle.setText(song.getTitle());
|
||||
holder.songArtist.setText(song.getArtistName());
|
||||
|
||||
CustomGlideRequest.Builder
|
||||
.from(context, song.getPrimary(), song.getBlurHash(), CustomGlideRequest.PRIMARY, CustomGlideRequest.TOP_QUALITY)
|
||||
.build()
|
||||
.into(holder.cover);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return songs.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
TextView songTitle;
|
||||
TextView songArtist;
|
||||
ImageView cover;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
songTitle = itemView.findViewById(R.id.queue_song_title_text_view);
|
||||
songArtist = itemView.findViewById(R.id.queue_song_artist_text_view);
|
||||
cover = itemView.findViewById(R.id.queue_song_cover_image_view);
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
SongRepository songRepository = new SongRepository(App.getInstance());
|
||||
QueueRepository queueRepository = new QueueRepository(App.getInstance());
|
||||
|
||||
songRepository.increasePlayCount(songs.get(getAdapterPosition()));
|
||||
}
|
||||
}
|
||||
|
||||
public void setItems(List<Song> songs) {
|
||||
this.songs = songs;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public Song getItem(int id) {
|
||||
return songs.get(id);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,9 @@ import com.cappielloantonio.play.App;
|
|||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.repository.QueueRepository;
|
||||
import com.cappielloantonio.play.repository.SongRepository;
|
||||
import com.cappielloantonio.play.ui.activities.MainActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -29,10 +31,12 @@ public class RecentMusicAdapter extends RecyclerView.Adapter<RecentMusicAdapter.
|
|||
|
||||
private List<Song> songs;
|
||||
private LayoutInflater mInflater;
|
||||
private MainActivity mainActivity;
|
||||
private Context context;
|
||||
private FragmentManager fragmentManager;
|
||||
|
||||
public RecentMusicAdapter(Context context, FragmentManager fragmentManager) {
|
||||
public RecentMusicAdapter(MainActivity mainActivity, Context context, FragmentManager fragmentManager) {
|
||||
this.mainActivity = mainActivity;
|
||||
this.context = context;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.mInflater = LayoutInflater.from(context);
|
||||
|
|
@ -82,7 +86,12 @@ public class RecentMusicAdapter extends RecyclerView.Adapter<RecentMusicAdapter.
|
|||
@Override
|
||||
public void onClick(View view) {
|
||||
SongRepository songRepository = new SongRepository(App.getInstance());
|
||||
QueueRepository queueRepository = new QueueRepository(App.getInstance());
|
||||
|
||||
songRepository.increasePlayCount(songs.get(getAdapterPosition()));
|
||||
queueRepository.insertAllAndStartNew(songs.subList(getAdapterPosition(), songs.size()));
|
||||
|
||||
mainActivity.isBottomSheetInPeek(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ import com.cappielloantonio.play.App;
|
|||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.repository.QueueRepository;
|
||||
import com.cappielloantonio.play.repository.SongRepository;
|
||||
import com.cappielloantonio.play.ui.activities.MainActivity;
|
||||
import com.cappielloantonio.play.util.Util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -30,10 +32,12 @@ public class SongResultSearchAdapter extends RecyclerView.Adapter<SongResultSear
|
|||
|
||||
private List<Song> songs;
|
||||
private LayoutInflater mInflater;
|
||||
private MainActivity mainActivity;
|
||||
private Context context;
|
||||
private FragmentManager fragmentManager;
|
||||
|
||||
public SongResultSearchAdapter(Context context, FragmentManager fragmentManager) {
|
||||
public SongResultSearchAdapter(MainActivity mainActivity, Context context, FragmentManager fragmentManager) {
|
||||
this.mainActivity = mainActivity;
|
||||
this.context = context;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.mInflater = LayoutInflater.from(context);
|
||||
|
|
@ -86,7 +90,12 @@ public class SongResultSearchAdapter extends RecyclerView.Adapter<SongResultSear
|
|||
@Override
|
||||
public void onClick(View view) {
|
||||
SongRepository songRepository = new SongRepository(App.getInstance());
|
||||
QueueRepository queueRepository = new QueueRepository(App.getInstance());
|
||||
|
||||
songRepository.increasePlayCount(songs.get(getAdapterPosition()));
|
||||
queueRepository.insertAllAndStartNew(songs.subList(getAdapterPosition(), songs.size()));
|
||||
|
||||
mainActivity.isBottomSheetInPeek(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -106,5 +115,4 @@ public class SongResultSearchAdapter extends RecyclerView.Adapter<SongResultSear
|
|||
public Song getItem(int id) {
|
||||
return songs.get(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ public class ConnectivityStatusBroadcastReceiver extends BroadcastReceiver {
|
|||
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
|
||||
|
||||
if (noConnectivity) {
|
||||
activity.activityMainBinding.offlineModeLinearLayout.setVisibility(View.VISIBLE);
|
||||
activity.bind.offlineModeTextView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
activity.activityMainBinding.offlineModeLinearLayout.setVisibility(View.GONE);
|
||||
activity.bind.offlineModeTextView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.cappielloantonio.play.database.dao.AlbumDao;
|
|||
import com.cappielloantonio.play.database.dao.ArtistDao;
|
||||
import com.cappielloantonio.play.database.dao.GenreDao;
|
||||
import com.cappielloantonio.play.database.dao.PlaylistDao;
|
||||
import com.cappielloantonio.play.database.dao.QueueDao;
|
||||
import com.cappielloantonio.play.database.dao.RecentSearchDao;
|
||||
import com.cappielloantonio.play.database.dao.SongDao;
|
||||
import com.cappielloantonio.play.database.dao.SongGenreCrossDao;
|
||||
|
|
@ -17,11 +18,12 @@ import com.cappielloantonio.play.model.Album;
|
|||
import com.cappielloantonio.play.model.Artist;
|
||||
import com.cappielloantonio.play.model.Genre;
|
||||
import com.cappielloantonio.play.model.Playlist;
|
||||
import com.cappielloantonio.play.model.Queue;
|
||||
import com.cappielloantonio.play.model.RecentSearch;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.model.SongGenreCross;
|
||||
|
||||
@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class}, version = 5, exportSchema = false)
|
||||
@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class, Queue.class}, version = 6, exportSchema = false)
|
||||
public abstract class AppDatabase extends RoomDatabase {
|
||||
private static final String TAG = "AppDatabase";
|
||||
|
||||
|
|
@ -51,4 +53,6 @@ public abstract class AppDatabase extends RoomDatabase {
|
|||
public abstract RecentSearchDao recentSearchDao();
|
||||
|
||||
public abstract SongGenreCrossDao songGenreCrossDao();
|
||||
|
||||
public abstract QueueDao queueDao();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package com.cappielloantonio.play.database.dao;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
|
||||
import com.cappielloantonio.play.model.Queue;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Dao
|
||||
public interface QueueDao {
|
||||
@Query("SELECT * FROM song JOIN queue ON song.id = queue.song_id")
|
||||
LiveData<List<Song>> getAll();
|
||||
|
||||
@Query("SELECT * FROM song JOIN queue ON song.id = queue.song_id")
|
||||
List<Song> getAllSimple();
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(Queue songQueueObject);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insertAll(List<Queue> songQueueObject);
|
||||
|
||||
@Delete
|
||||
void delete(Queue songQueueObject);
|
||||
|
||||
@Query("DELETE FROM queue")
|
||||
void deleteAll();
|
||||
|
||||
@Query("SELECT COUNT(*) FROM queue;")
|
||||
int count();
|
||||
}
|
||||
44
app/src/main/java/com/cappielloantonio/play/model/Queue.java
Normal file
44
app/src/main/java/com/cappielloantonio/play/model/Queue.java
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package com.cappielloantonio.play.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
@Entity(tableName = "queue")
|
||||
public class Queue {
|
||||
@NonNull
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = "id")
|
||||
private int id;
|
||||
|
||||
@ColumnInfo(name = "song_id")
|
||||
private String songID;
|
||||
|
||||
public Queue(@NonNull int id, String songID) {
|
||||
this.id = id;
|
||||
this.songID = songID;
|
||||
}
|
||||
|
||||
@Ignore
|
||||
public Queue(String songID) {
|
||||
this.songID = songID;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSongID() {
|
||||
return songID;
|
||||
}
|
||||
|
||||
public void setSongID(String songID) {
|
||||
this.songID = songID;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
package com.cappielloantonio.play.repository;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import com.cappielloantonio.play.database.AppDatabase;
|
||||
import com.cappielloantonio.play.database.dao.QueueDao;
|
||||
import com.cappielloantonio.play.model.Queue;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.util.QueueUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QueueRepository {
|
||||
private static final String TAG = "QueueRepository";
|
||||
|
||||
private QueueDao queueDao;
|
||||
private LiveData<List<Song>> listLiveQueue;
|
||||
|
||||
public QueueRepository(Application application) {
|
||||
AppDatabase database = AppDatabase.getInstance(application);
|
||||
queueDao = database.queueDao();
|
||||
}
|
||||
|
||||
public LiveData<List<Song>> getLiveQueue() {
|
||||
listLiveQueue = queueDao.getAll();
|
||||
return listLiveQueue;
|
||||
}
|
||||
|
||||
public List<Song> getSongs() {
|
||||
List<Song> songs = new ArrayList<>();
|
||||
|
||||
GetSongsThreadSafe getSongs = new GetSongsThreadSafe(queueDao);
|
||||
Thread thread = new Thread(getSongs);
|
||||
thread.start();
|
||||
|
||||
try {
|
||||
thread.join();
|
||||
songs = getSongs.getSongs();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return songs;
|
||||
}
|
||||
|
||||
public void insert(Song song) {
|
||||
InsertThreadSafe insert = new InsertThreadSafe(queueDao, song);
|
||||
Thread thread = new Thread(insert);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void insertAll(List<Song> songs) {
|
||||
InsertAllThreadSafe insertAll = new InsertAllThreadSafe(queueDao, songs);
|
||||
Thread thread = new Thread(insertAll);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void insertAllAndStartNew(List<Song> songs) {
|
||||
try {
|
||||
final Thread delete = new Thread(new DeleteAllThreadSafe(queueDao));
|
||||
final Thread insertAll = new Thread(new InsertAllThreadSafe(queueDao, songs));
|
||||
|
||||
delete.start();
|
||||
delete.join();
|
||||
insertAll.start();
|
||||
insertAll.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(Queue queueElement) {
|
||||
DeleteThreadSafe delete = new DeleteThreadSafe(queueDao, queueElement);
|
||||
Thread thread = new Thread(delete);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void deleteAll() {
|
||||
DeleteAllThreadSafe delete = new DeleteAllThreadSafe(queueDao);
|
||||
Thread thread = new Thread(delete);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public int count() {
|
||||
int count = 0;
|
||||
|
||||
CountThreadSafe countThread = new CountThreadSafe(queueDao);
|
||||
Thread thread = new Thread(countThread);
|
||||
thread.start();
|
||||
|
||||
try {
|
||||
thread.join();
|
||||
count = countThread.getCount();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
private static class InsertThreadSafe implements Runnable {
|
||||
private QueueDao queueDao;
|
||||
private Song song;
|
||||
|
||||
public InsertThreadSafe(QueueDao queueDao, Song song) {
|
||||
this.queueDao = queueDao;
|
||||
this.song = song;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
queueDao.insert(QueueUtil.getQueueElementFromSong(song));
|
||||
}
|
||||
}
|
||||
|
||||
private static class InsertAllThreadSafe implements Runnable {
|
||||
private QueueDao queueDao;
|
||||
private List<Song> songs;
|
||||
|
||||
public InsertAllThreadSafe(QueueDao queueDao, List<Song> songs) {
|
||||
this.queueDao = queueDao;
|
||||
this.songs = songs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
queueDao.insertAll(QueueUtil.getQueueElementsFromSongs(songs));
|
||||
}
|
||||
}
|
||||
|
||||
private static class DeleteThreadSafe implements Runnable {
|
||||
private QueueDao queueDao;
|
||||
private Queue queueElement;
|
||||
|
||||
public DeleteThreadSafe(QueueDao queueDao, Queue queueElement) {
|
||||
this.queueDao = queueDao;
|
||||
this.queueElement = queueElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
queueDao.delete(queueElement);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DeleteAllThreadSafe implements Runnable {
|
||||
private QueueDao queueDao;
|
||||
|
||||
public DeleteAllThreadSafe(QueueDao queueDao) {
|
||||
this.queueDao = queueDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
queueDao.deleteAll();
|
||||
}
|
||||
}
|
||||
|
||||
private static class CountThreadSafe implements Runnable {
|
||||
private QueueDao queueDao;
|
||||
private int count = 0;
|
||||
|
||||
public CountThreadSafe(QueueDao queueDao) {
|
||||
this.queueDao = queueDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
count = queueDao.count();
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
private static class GetSongsThreadSafe implements Runnable {
|
||||
private QueueDao queueDao;
|
||||
private List<Song> songs;
|
||||
|
||||
public GetSongsThreadSafe(QueueDao queueDao) {
|
||||
this.queueDao = queueDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
songs = queueDao.getAllSimple();
|
||||
}
|
||||
|
||||
public List<Song> getSongs() {
|
||||
return songs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,12 @@ package com.cappielloantonio.play.ui.activities;
|
|||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.navigation.ui.NavigationUI;
|
||||
|
|
@ -15,9 +18,12 @@ import com.cappielloantonio.play.R;
|
|||
import com.cappielloantonio.play.broadcast.receiver.ConnectivityStatusBroadcastReceiver;
|
||||
import com.cappielloantonio.play.databinding.ActivityMainBinding;
|
||||
import com.cappielloantonio.play.ui.activities.base.BaseActivity;
|
||||
import com.cappielloantonio.play.ui.fragment.PlayerBottomSheetFragment;
|
||||
import com.cappielloantonio.play.util.PreferenceUtil;
|
||||
import com.cappielloantonio.play.util.SyncUtil;
|
||||
import com.cappielloantonio.play.viewmodel.MainViewModel;
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
|
||||
import org.jellyfin.apiclient.interaction.EmptyResponse;
|
||||
import org.jellyfin.apiclient.interaction.Response;
|
||||
|
|
@ -29,21 +35,27 @@ import java.util.Objects;
|
|||
public class MainActivity extends BaseActivity {
|
||||
private static final String TAG = "MainActivity";
|
||||
|
||||
public ActivityMainBinding activityMainBinding;
|
||||
public ActivityMainBinding bind;
|
||||
private MainViewModel mainViewModel;
|
||||
|
||||
private FragmentManager fragmentManager;
|
||||
private NavHostFragment navHostFragment;
|
||||
private BottomNavigationView bottomNavigationView;
|
||||
public NavController navController;
|
||||
private BottomSheetBehavior bottomSheetBehavior;
|
||||
|
||||
ConnectivityStatusBroadcastReceiver connectivityStatusBroadcastReceiver;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
View view = activityMainBinding.getRoot();
|
||||
|
||||
bind = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
View view = bind.getRoot();
|
||||
setContentView(view);
|
||||
|
||||
mainViewModel = new ViewModelProvider(this).get(MainViewModel.class);
|
||||
|
||||
connectivityStatusBroadcastReceiver = new ConnectivityStatusBroadcastReceiver(this);
|
||||
connectivityStatusReceiverManager(true);
|
||||
|
||||
|
|
@ -58,11 +70,9 @@ public class MainActivity extends BaseActivity {
|
|||
|
||||
public void init() {
|
||||
fragmentManager = getSupportFragmentManager();
|
||||
bottomNavigationView = findViewById(R.id.bottom_navigation);
|
||||
|
||||
navHostFragment = (NavHostFragment) fragmentManager.findFragmentById(R.id.nav_host_fragment);
|
||||
navController = navHostFragment.getNavController();
|
||||
NavigationUI.setupWithNavController(bottomNavigationView, navController);
|
||||
initBottomSheet();
|
||||
initNavigation();
|
||||
|
||||
if (PreferenceUtil.getInstance(this).getToken() != null) {
|
||||
checkPreviousSession();
|
||||
|
|
@ -71,6 +81,42 @@ public class MainActivity extends BaseActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private void initBottomSheet() {
|
||||
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.player_bottom_sheet));
|
||||
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallback);
|
||||
fragmentManager.beginTransaction().replace(R.id.player_bottom_sheet, new PlayerBottomSheetFragment(), "PlayerBottomSheet").commit();
|
||||
|
||||
isBottomSheetInPeek(mainViewModel.isQueueLoaded());
|
||||
}
|
||||
|
||||
public void isBottomSheetInPeek(Boolean isVisible) {
|
||||
|
||||
Log.d(TAG, "isBottomSheetInPeek: " + isVisible);
|
||||
|
||||
if (isVisible) {
|
||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||
} else {
|
||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
private void initNavigation() {
|
||||
bottomNavigationView = findViewById(R.id.bottom_navigation);
|
||||
navHostFragment = (NavHostFragment) fragmentManager.findFragmentById(R.id.nav_host_fragment);
|
||||
navController = navHostFragment.getNavController();
|
||||
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
|
||||
if(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED && (
|
||||
destination.getId() == R.id.homeFragment ||
|
||||
destination.getId() == R.id.libraryFragment ||
|
||||
destination.getId() == R.id.searchFragment ||
|
||||
destination.getId() == R.id.settingsFragment)
|
||||
) {
|
||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||
}
|
||||
});
|
||||
NavigationUI.setupWithNavController(bottomNavigationView, navController);
|
||||
}
|
||||
|
||||
private void checkPreviousSession() {
|
||||
App.getApiClientInstance(getApplicationContext()).ChangeServerLocation(PreferenceUtil.getInstance(this).getServer());
|
||||
App.getApiClientInstance(getApplicationContext()).SetAuthenticationInfo(PreferenceUtil.getInstance(this).getToken(), PreferenceUtil.getInstance(this).getUser());
|
||||
|
|
@ -94,8 +140,6 @@ public class MainActivity extends BaseActivity {
|
|||
});
|
||||
}
|
||||
|
||||
// True: VISIBLE
|
||||
// False: GONE
|
||||
public void setBottomNavigationBarVisibility(boolean visibility) {
|
||||
if (visibility) {
|
||||
bottomNavigationView.setVisibility(View.VISIBLE);
|
||||
|
|
@ -104,13 +148,50 @@ public class MainActivity extends BaseActivity {
|
|||
}
|
||||
}
|
||||
|
||||
public void setBottomSheetVisibility(boolean visibility) {
|
||||
if (visibility) {
|
||||
findViewById(R.id.player_bottom_sheet).setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
findViewById(R.id.player_bottom_sheet).setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private BottomSheetBehavior.BottomSheetCallback bottomSheetCallback =
|
||||
new BottomSheetBehavior.BottomSheetCallback() {
|
||||
@Override
|
||||
public void onStateChanged(@NonNull View view, int state) {
|
||||
switch (state) {
|
||||
case BottomSheetBehavior.STATE_COLLAPSED:
|
||||
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
|
||||
if(playerBottomSheetFragment == null) break;
|
||||
|
||||
playerBottomSheetFragment.scrollOnTop();
|
||||
break;
|
||||
case BottomSheetBehavior.STATE_HIDDEN:
|
||||
mainViewModel.deleteQueue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlide(@NonNull View view, float slideOffset) {
|
||||
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
|
||||
if(playerBottomSheetFragment == null) return;
|
||||
|
||||
float condensedSlideOffset = Math.max(0.0f, Math.min(0.2f, slideOffset - 0.2f)) / 0.2f;
|
||||
playerBottomSheetFragment.getPlayerHeader().setAlpha(1 - condensedSlideOffset);
|
||||
playerBottomSheetFragment.getPlayerHeader().setVisibility(condensedSlideOffset > 0.99 ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
};
|
||||
|
||||
public void goToLogin() {
|
||||
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment)
|
||||
navController.navigate(R.id.action_landingFragment_to_loginFragment);
|
||||
}
|
||||
|
||||
public void goToSync() {
|
||||
bottomNavigationView.setVisibility(View.GONE);
|
||||
setBottomNavigationBarVisibility(false);
|
||||
setBottomSheetVisibility(false);
|
||||
|
||||
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.loginFragment) {
|
||||
Bundle bundle = SyncUtil.getSyncBundle(true, true, true, true, true, false);
|
||||
|
|
@ -145,12 +226,19 @@ public class MainActivity extends BaseActivity {
|
|||
}
|
||||
|
||||
private void connectivityStatusReceiverManager(boolean isActive) {
|
||||
if(isActive) {
|
||||
if (isActive) {
|
||||
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
registerReceiver(connectivityStatusBroadcastReceiver, filter);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
unregisterReceiver(connectivityStatusBroadcastReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED)
|
||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||
else
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,18 @@
|
|||
package com.cappielloantonio.play.ui.fragment;
|
||||
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
|
||||
import com.cappielloantonio.play.databinding.FragmentAlbumPageBinding;
|
||||
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||
|
|
@ -24,7 +28,14 @@ public class AlbumPageFragment extends Fragment {
|
|||
private SongResultSearchAdapter songResultSearchAdapter;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
initAppBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
activity = (MainActivity) getActivity();
|
||||
|
||||
bind = FragmentAlbumPageBinding.inflate(inflater, container, false);
|
||||
|
|
@ -50,6 +61,29 @@ public class AlbumPageFragment extends Fragment {
|
|||
bind = null;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
albumPageViewModel.setAlbum(getArguments().getParcelable("album_object"));
|
||||
}
|
||||
|
||||
private void initAppBar() {
|
||||
activity.setSupportActionBar(bind.animToolbar);
|
||||
if (activity.getSupportActionBar() != null)
|
||||
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
bind.collapsingToolbar.setTitle(albumPageViewModel.getAlbum().getTitle());
|
||||
bind.animToolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp());
|
||||
bind.collapsingToolbar.setCollapsedTitleTextColor(getResources().getColor(R.color.titleTextColor, null));
|
||||
|
||||
bind.appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
|
||||
if ((bind.collapsingToolbar.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.collapsingToolbar))) {
|
||||
bind.animToolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.titleTextColor, null), PorterDuff.Mode.SRC_ATOP);
|
||||
} else {
|
||||
bind.animToolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.white, null), PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initBackCover() {
|
||||
CustomGlideRequest.Builder
|
||||
.from(requireContext(), albumPageViewModel.getAlbum().getPrimary(), albumPageViewModel.getAlbum().getBlurHash(), CustomGlideRequest.PRIMARY, CustomGlideRequest.TOP_QUALITY)
|
||||
|
|
@ -57,17 +91,11 @@ public class AlbumPageFragment extends Fragment {
|
|||
.into(bind.albumBackCoverImageView);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
albumPageViewModel.setAlbum(getArguments().getParcelable("album_object"));
|
||||
|
||||
bind.albumTitleLabel.setText(albumPageViewModel.getAlbum().getTitle());
|
||||
}
|
||||
|
||||
private void initSongsView() {
|
||||
bind.songRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
bind.songRecyclerView.setHasFixedSize(true);
|
||||
|
||||
songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
|
||||
songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.songRecyclerView.setAdapter(songResultSearchAdapter);
|
||||
albumPageViewModel.getAlbumSongList().observe(requireActivity(), songs -> songResultSearchAdapter.setItems(songs));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package com.cappielloantonio.play.ui.fragment;
|
||||
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
|
@ -27,6 +30,13 @@ public class ArtistPageFragment extends Fragment {
|
|||
private SongResultSearchAdapter songResultSearchAdapter;
|
||||
private AlbumArtistPageAdapter albumArtistPageAdapter;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
initAppBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
activity = (MainActivity) getActivity();
|
||||
|
|
@ -58,7 +68,6 @@ public class ArtistPageFragment extends Fragment {
|
|||
|
||||
private void init() {
|
||||
artistPageViewModel.setArtist(getArguments().getParcelable("artist_object"));
|
||||
bind.artistNameLabel.setText(artistPageViewModel.getArtist().getName());
|
||||
|
||||
bind.mostStreamedSongTextViewClickable.setOnClickListener(v -> {
|
||||
Bundle bundle = new Bundle();
|
||||
|
|
@ -68,6 +77,24 @@ public class ArtistPageFragment extends Fragment {
|
|||
});
|
||||
}
|
||||
|
||||
private void initAppBar() {
|
||||
activity.setSupportActionBar(bind.animToolbar);
|
||||
if (activity.getSupportActionBar() != null)
|
||||
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
bind.collapsingToolbar.setTitle(artistPageViewModel.getArtist().getName());
|
||||
bind.animToolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp());
|
||||
bind.collapsingToolbar.setCollapsedTitleTextColor(getResources().getColor(R.color.titleTextColor, null));
|
||||
|
||||
bind.appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
|
||||
if ((bind.collapsingToolbar.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.collapsingToolbar))) {
|
||||
bind.animToolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.titleTextColor, null), PorterDuff.Mode.SRC_ATOP);
|
||||
} else {
|
||||
bind.animToolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.white, null), PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initBackdrop() {
|
||||
CustomGlideRequest.Builder
|
||||
.from(requireContext(), artistPageViewModel.getArtist().getBackdrop(), artistPageViewModel.getArtist().getBackdropBlurHash(), CustomGlideRequest.BACKDROP, CustomGlideRequest.TOP_QUALITY)
|
||||
|
|
@ -77,16 +104,14 @@ public class ArtistPageFragment extends Fragment {
|
|||
|
||||
private void initTopSongsView() {
|
||||
bind.mostStreamedSongRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
bind.mostStreamedSongRecyclerView.setHasFixedSize(true);
|
||||
|
||||
songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
|
||||
songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.mostStreamedSongRecyclerView.setAdapter(songResultSearchAdapter);
|
||||
artistPageViewModel.getArtistTopSongList().observe(requireActivity(), songs -> songResultSearchAdapter.setItems(songs));
|
||||
}
|
||||
|
||||
private void initAlbumsView() {
|
||||
bind.albumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||
bind.albumsRecyclerView.setHasFixedSize(true);
|
||||
|
||||
albumArtistPageAdapter = new AlbumArtistPageAdapter(requireContext());
|
||||
bind.albumsRecyclerView.setAdapter(albumArtistPageAdapter);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ public class HomeFragment extends Fragment {
|
|||
public void onStart() {
|
||||
super.onStart();
|
||||
activity.setBottomNavigationBarVisibility(true);
|
||||
activity.setBottomSheetVisibility(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -123,14 +124,14 @@ public class HomeFragment extends Fragment {
|
|||
discoverSongAdapter = new DiscoverSongAdapter(requireContext(), homeViewModel.getDiscoverSongList());
|
||||
bind.discoverSongViewPager.setAdapter(discoverSongAdapter);
|
||||
bind.discoverSongViewPager.setOffscreenPageLimit(3);
|
||||
settDiscoverSongSlideViewOffset(20, 16);
|
||||
setDiscoverSongSlideViewOffset(20, 16);
|
||||
}
|
||||
|
||||
private void initRecentAddedSongView() {
|
||||
bind.recentlyAddedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||
bind.recentlyAddedTracksRecyclerView.setHasFixedSize(true);
|
||||
|
||||
recentlyAddedMusicAdapter = new RecentMusicAdapter(requireContext(), getChildFragmentManager());
|
||||
recentlyAddedMusicAdapter = new RecentMusicAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.recentlyAddedTracksRecyclerView.setAdapter(recentlyAddedMusicAdapter);
|
||||
homeViewModel.getRecentlyAddedSongList().observe(requireActivity(), songs -> recentlyAddedMusicAdapter.setItems(songs));
|
||||
}
|
||||
|
|
@ -153,7 +154,7 @@ public class HomeFragment extends Fragment {
|
|||
bind.favoritesTracksRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 5, GridLayoutManager.HORIZONTAL, false));
|
||||
bind.favoritesTracksRecyclerView.setHasFixedSize(true);
|
||||
|
||||
favoriteSongAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
|
||||
favoriteSongAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.favoritesTracksRecyclerView.setAdapter(favoriteSongAdapter);
|
||||
homeViewModel.getFavorites().observe(requireActivity(), songs -> favoriteSongAdapter.setItems(songs));
|
||||
|
||||
|
|
@ -165,7 +166,7 @@ public class HomeFragment extends Fragment {
|
|||
bind.mostPlayedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||
bind.mostPlayedTracksRecyclerView.setHasFixedSize(true);
|
||||
|
||||
mostPlayedMusicAdapter = new RecentMusicAdapter(requireContext(), getChildFragmentManager());
|
||||
mostPlayedMusicAdapter = new RecentMusicAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.mostPlayedTracksRecyclerView.setAdapter(mostPlayedMusicAdapter);
|
||||
homeViewModel.getMostPlayedSongList().observe(requireActivity(), songs -> mostPlayedMusicAdapter.setItems(songs));
|
||||
}
|
||||
|
|
@ -174,12 +175,12 @@ public class HomeFragment extends Fragment {
|
|||
bind.recentlyPlayedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||
bind.recentlyPlayedTracksRecyclerView.setHasFixedSize(true);
|
||||
|
||||
recentlyPlayedMusicAdapter = new RecentMusicAdapter(requireContext(), getChildFragmentManager());
|
||||
recentlyPlayedMusicAdapter = new RecentMusicAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.recentlyPlayedTracksRecyclerView.setAdapter(recentlyPlayedMusicAdapter);
|
||||
homeViewModel.getRecentlyPlayedSongList().observe(requireActivity(), songs -> recentlyPlayedMusicAdapter.setItems(songs));
|
||||
}
|
||||
|
||||
private void settDiscoverSongSlideViewOffset(float pageOffset, float pageMargin) {
|
||||
private void setDiscoverSongSlideViewOffset(float pageOffset, float pageMargin) {
|
||||
bind.discoverSongViewPager.setPageTransformer((page, position) -> {
|
||||
float myOffset = position * -(2 * pageOffset + pageMargin);
|
||||
if (bind.discoverSongViewPager.getOrientation() == ViewPager2.ORIENTATION_HORIZONTAL) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
package com.cappielloantonio.play.ui.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.adapter.PlayerNowPlayingSongAdapter;
|
||||
import com.cappielloantonio.play.adapter.PlayerSongQueueAdapter;
|
||||
import com.cappielloantonio.play.databinding.FragmentPlayerBottomSheetBinding;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.ui.activities.MainActivity;
|
||||
import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
|
||||
|
||||
public class PlayerBottomSheetFragment extends Fragment {
|
||||
private static final String TAG = "PlayerBottomSheetFragment";
|
||||
|
||||
private FragmentPlayerBottomSheetBinding bind;
|
||||
private MainActivity activity;
|
||||
private PlayerBottomSheetViewModel playerBottomSheetViewModel;
|
||||
|
||||
private PlayerNowPlayingSongAdapter playerNowPlayingSongAdapter;
|
||||
private PlayerSongQueueAdapter playerSongQueueAdapter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
activity = (MainActivity) getActivity();
|
||||
|
||||
bind = FragmentPlayerBottomSheetBinding.inflate(inflater, container, false);
|
||||
View view = bind.getRoot();
|
||||
playerBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(PlayerBottomSheetViewModel.class);
|
||||
|
||||
initQueueSlideView();
|
||||
initQueueRecyclerView();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initQueueSlideView() {
|
||||
bind.playerSongCoverViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
|
||||
|
||||
playerNowPlayingSongAdapter = new PlayerNowPlayingSongAdapter(requireContext());
|
||||
bind.playerSongCoverViewPager.setAdapter(playerNowPlayingSongAdapter);
|
||||
playerBottomSheetViewModel.getQueueSong().observe(requireActivity(), songs -> playerNowPlayingSongAdapter.setItems(songs));
|
||||
|
||||
bind.playerSongCoverViewPager.setOffscreenPageLimit(3);
|
||||
setDiscoverSongSlideViewOffset(40, 4);
|
||||
|
||||
bind.playerSongCoverViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||
|
||||
playerBottomSheetViewModel.setNowPlayingSong(position);
|
||||
}
|
||||
});
|
||||
|
||||
playerBottomSheetViewModel.getNowPlayingSong().observe(requireActivity(), song -> {
|
||||
if(song != null)
|
||||
setSongInfo(song);
|
||||
});
|
||||
}
|
||||
|
||||
private void initQueueRecyclerView() {
|
||||
bind.playerQueueRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
bind.playerQueueRecyclerView.setHasFixedSize(true);
|
||||
|
||||
playerSongQueueAdapter = new PlayerSongQueueAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.playerQueueRecyclerView.setAdapter(playerSongQueueAdapter);
|
||||
playerBottomSheetViewModel.getQueueSong().observe(requireActivity(), songs -> playerSongQueueAdapter.setItems(songs));
|
||||
}
|
||||
|
||||
private void setDiscoverSongSlideViewOffset(float pageOffset, float pageMargin) {
|
||||
bind.playerSongCoverViewPager.setPageTransformer((page, position) -> {
|
||||
float myOffset = position * -(2 * pageOffset + pageMargin);
|
||||
if (bind.playerSongCoverViewPager.getOrientation() == ViewPager2.ORIENTATION_HORIZONTAL) {
|
||||
if (ViewCompat.getLayoutDirection(bind.playerSongCoverViewPager) == ViewCompat.LAYOUT_DIRECTION_RTL) {
|
||||
page.setTranslationX(-myOffset);
|
||||
} else {
|
||||
page.setTranslationX(myOffset);
|
||||
}
|
||||
} else {
|
||||
page.setTranslationY(myOffset);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setSongInfo(Song song) {
|
||||
if(song != null) {
|
||||
bind.playerSongTitleLabel.setText(song.getTitle());
|
||||
bind.playerArtistNameLabel.setText(song.getArtistName());
|
||||
}
|
||||
}
|
||||
|
||||
public View getPlayerHeader() {
|
||||
return getView().findViewById(R.id.player_header_layout);
|
||||
}
|
||||
|
||||
public void scrollOnTop() {
|
||||
bind.playerNestedScrollView.fullScroll(ScrollView.FOCUS_UP);
|
||||
}
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ public class SearchFragment extends Fragment {
|
|||
bind.searchResultTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
bind.searchResultTracksRecyclerView.setHasFixedSize(true);
|
||||
|
||||
songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
|
||||
songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.searchResultTracksRecyclerView.setAdapter(songResultSearchAdapter);
|
||||
|
||||
// Albums
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public class SongListPageFragment extends Fragment {
|
|||
bind.songListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
bind.songListRecyclerView.setHasFixedSize(true);
|
||||
|
||||
songResultSearchAdapter = new SongResultSearchAdapter(requireContext(), getChildFragmentManager());
|
||||
songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager());
|
||||
bind.songListRecyclerView.setAdapter(songResultSearchAdapter);
|
||||
songListPageViewModel.getSongList().observe(requireActivity(), songs -> songResultSearchAdapter.setItems(songs));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public class PreferenceUtil {
|
|||
}
|
||||
|
||||
public String getToken() {
|
||||
return mPreferences.getString(TOKEN, "");
|
||||
return mPreferences.getString(TOKEN, null);
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.cappielloantonio.play.util;
|
||||
|
||||
import com.cappielloantonio.play.model.Queue;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QueueUtil {
|
||||
public static Queue getQueueElementFromSong(Song song) {
|
||||
return new Queue(song.getId());
|
||||
}
|
||||
|
||||
public static List<Queue> getQueueElementsFromSongs(List<Song> songs) {
|
||||
List<Queue> queue = new ArrayList<>();
|
||||
|
||||
for(Song song: songs) {
|
||||
queue.add(new Queue(song.getId()));
|
||||
}
|
||||
|
||||
return queue;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package com.cappielloantonio.play.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class Util {
|
||||
|
|
@ -15,4 +17,12 @@ public class Util {
|
|||
return String.format(Locale.getDefault(), "%d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
}
|
||||
|
||||
public static float dpFromPx(final Context context, final float px) {
|
||||
return px / context.getResources().getDisplayMetrics().density;
|
||||
}
|
||||
|
||||
public static float pxFromDp(final Context context, final float dp) {
|
||||
return dp * context.getResources().getDisplayMetrics().density;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
package com.cappielloantonio.play.viewmodel;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
|
||||
import com.cappielloantonio.play.repository.QueueRepository;
|
||||
|
||||
public class MainViewModel extends AndroidViewModel {
|
||||
private static final String TAG = "SearchViewModel";
|
||||
|
||||
private QueueRepository queueRepository;
|
||||
|
||||
public MainViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
|
||||
queueRepository = new QueueRepository(application);
|
||||
}
|
||||
|
||||
public boolean isQueueLoaded() {
|
||||
if(queueRepository.count() == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void deleteQueue(){
|
||||
queueRepository.deleteAll();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.cappielloantonio.play.viewmodel;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.repository.QueueRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerBottomSheetViewModel extends AndroidViewModel {
|
||||
private static final String TAG = "HomeViewModel";
|
||||
private QueueRepository queueRepository;
|
||||
|
||||
private LiveData<List<Song>> queueSong;
|
||||
private LiveData<Song> nowPlayingSong = new MutableLiveData<>();
|
||||
|
||||
|
||||
public PlayerBottomSheetViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
|
||||
queueRepository = new QueueRepository(application);
|
||||
|
||||
queueSong = queueRepository.getLiveQueue();
|
||||
}
|
||||
|
||||
public LiveData<List<Song>> getQueueSong() {
|
||||
return queueSong;
|
||||
}
|
||||
|
||||
public LiveData<Song> getNowPlayingSong() {
|
||||
return nowPlayingSong;
|
||||
}
|
||||
|
||||
public LiveData<Song> setNowPlayingSong(int position) {
|
||||
Song song = queueRepository.getSongs().get(position);
|
||||
|
||||
if(song != null) {
|
||||
nowPlayingSong = new MutableLiveData<>(song);
|
||||
}
|
||||
|
||||
return nowPlayingSong;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_thumb_up" android:state_checked="true" android:color="@color/titleTextColor"/>
|
||||
<item android:drawable="@drawable/ic_thumb_up_outlined" android:state_checked="false" android:color="@color/titleTextColor" />
|
||||
<item android:drawable="@drawable/ic_favorite" android:state_checked="true" android:color="@color/titleTextColor"/>
|
||||
<item android:drawable="@drawable/ic_favorites_outlined" android:state_checked="false" android:color="@color/titleTextColor" />
|
||||
</selector>
|
||||
5
app/src/main/res/drawable/button_play_pause_selector.xml
Normal file
5
app/src/main/res/drawable/button_play_pause_selector.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_play_circle" android:state_checked="true" android:color="@color/titleTextColor"/>
|
||||
<item android:drawable="@drawable/ic_pause_circle" android:state_checked="false" android:color="@color/titleTextColor" />
|
||||
</selector>
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#00000000"
|
||||
android:endColor="#FF000000"
|
||||
android:angle="90"
|
||||
android:dither="true" />
|
||||
</shape>
|
||||
9
app/src/main/res/drawable/ic_collapse_arrow.xml
Normal file
9
app/src/main/res/drawable/ic_collapse_arrow.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15.88,9.29L12,13.17 8.12,9.29c-0.39,-0.39 -1.02,-0.39 -1.41,0 -0.39,0.39 -0.39,1.02 0,1.41l4.59,4.59c0.39,0.39 1.02,0.39 1.41,0l4.59,-4.59c0.39,-0.39 0.39,-1.02 0,-1.41 -0.39,-0.38 -1.03,-0.39 -1.42,0z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_drag_handle.xml
Normal file
9
app/src/main/res/drawable/ic_drag_handle.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/titleTextColor"
|
||||
android:pathData="M19,9H5c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h14c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1zM5,15h14c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1H5c-0.55,0 -1,0.45 -1,1s0.45,1 1,1z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_favorite.xml
Normal file
9
app/src/main/res/drawable/ic_favorite.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/titleTextColor"
|
||||
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
|
||||
</vector>
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:fillColor="@color/titleTextColor"
|
||||
android:pathData="M16.5,3c-1.74,0 -3.41,0.81 -4.5,2.09C10.91,3.81 9.24,3 7.5,3 4.42,3 2,5.42 2,8.5c0,3.78 3.4,6.86 8.55,11.54L12,21.35l1.45,-1.32C18.6,15.36 22,12.28 22,8.5 22,5.42 19.58,3 16.5,3zM12.1,18.55l-0.1,0.1 -0.1,-0.1C7.14,14.24 4,11.39 4,8.5 4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5 0,2.89 -3.14,5.74 -7.9,10.05z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_pause_circle.xml
Normal file
9
app/src/main/res/drawable/ic_pause_circle.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M10,16c0.55,0 1,-0.45 1,-1L11,9c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v6c0,0.55 0.45,1 1,1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM14,16c0.55,0 1,-0.45 1,-1L15,9c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v6c0,0.55 0.45,1 1,1z"/>
|
||||
</vector>
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:fillColor="@color/titleTextColor"
|
||||
android:pathData="M8,6.82v10.36c0,0.79 0.87,1.27 1.54,0.84l8.14,-5.18c0.62,-0.39 0.62,-1.29 0,-1.69L9.54,5.98C8.87,5.55 8,6.03 8,6.82z"/>
|
||||
</vector>
|
||||
|
|
|
|||
9
app/src/main/res/drawable/ic_play_circle.xml
Normal file
9
app/src/main/res/drawable/ic_play_circle.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M10.8,15.9l4.67,-3.5c0.27,-0.2 0.27,-0.6 0,-0.8L10.8,8.1c-0.33,-0.25 -0.8,-0.01 -0.8,0.4v7c0,0.41 0.47,0.65 0.8,0.4zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_skip_next.xml
Normal file
9
app/src/main/res/drawable/ic_skip_next.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M7.58,16.89l5.77,-4.07c0.56,-0.4 0.56,-1.24 0,-1.63L7.58,7.11C6.91,6.65 6,7.12 6,7.93v8.14c0,0.81 0.91,1.28 1.58,0.82zM16,7v10c0,0.55 0.45,1 1,1s1,-0.45 1,-1V7c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_skip_previous.xml
Normal file
9
app/src/main/res/drawable/ic_skip_previous.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M7,6c0.55,0 1,0.45 1,1v10c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1L6,7c0,-0.55 0.45,-1 1,-1zM10.66,12.82l5.77,4.07c0.66,0.47 1.58,-0.01 1.58,-0.82L18.01,7.93c0,-0.81 -0.91,-1.28 -1.58,-0.82l-5.77,4.07c-0.57,0.4 -0.57,1.24 0,1.64z"/>
|
||||
</vector>
|
||||
|
|
@ -1,50 +1,54 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:imeOptions="actionDone">
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_graph" />
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_graph"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/player_bottom_sheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottom_navigation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/bottom_nav_shape"
|
||||
android:elevation="2dp"
|
||||
android:visibility="gone"
|
||||
app:itemIconTint="@drawable/bottom_nav_selector"
|
||||
app:labelVisibilityMode="unlabeled"
|
||||
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap"
|
||||
app:menu="@menu/bottom_nav_menu">
|
||||
app:menu="@menu/bottom_nav_menu"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/offline_mode_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorAccent"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="center"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="6dp"
|
||||
android:text="Offline mode"/>
|
||||
</LinearLayout>
|
||||
</com.google.android.material.bottomnavigation.BottomNavigationView>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
<TextView
|
||||
android:id="@+id/offline_mode_text_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorAccent"
|
||||
android:gravity="center"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="6dp"
|
||||
android:text="Offline mode"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
|
@ -3,8 +3,7 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="20dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_progress_bar"
|
||||
|
|
@ -27,7 +26,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="8dp">
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -1,91 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="@dimen/appbar_header_height"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:backgroundTint="@color/cardColor"
|
||||
app:layout_constraintDimensionRatio="W, 4:5"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:cardCornerRadius="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/album_back_cover_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/gradient_backdrop_background_image" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/album_title_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="32dp"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@android:color/white"
|
||||
android:textFontWeight="900"
|
||||
android:textSize="40sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- Label and button -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:layout_marginTop="12dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:text="Songs"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/song_recycler_view"
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsing_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp" />
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
android:fitsSystemWindows="true"
|
||||
app:contentScrim="?attr/colorPrimary"
|
||||
app:expandedTitleMarginStart="@dimen/activity_margin_content"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/album_back_cover_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_collapseMode="parallax" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/appbar_header_height"
|
||||
android:layout_gravity="top"
|
||||
android:fitsSystemWindows="true"
|
||||
android:background="@drawable/gradient_backdrop_background_image"/>
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/anim_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:titleTextColor="@color/titleTextColor"
|
||||
app:layout_collapseMode="pin"
|
||||
app:popupTheme="@style/ThemeOverlay.MaterialComponents.Light" />
|
||||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/song_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="18dp"
|
||||
android:paddingBottom="@dimen/global_padding_bottom"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="20dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_progress_bar"
|
||||
|
|
@ -27,7 +25,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="8dp">
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -1,135 +1,128 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/appbar_header_height"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsing_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
app:contentScrim="?attr/colorPrimary"
|
||||
app:expandedTitleMarginStart="@dimen/activity_margin_content"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/artist_backdrop_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_collapseMode="parallax" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/appbar_header_height"
|
||||
android:layout_gravity="top"
|
||||
android:fitsSystemWindows="true"
|
||||
android:background="@drawable/gradient_backdrop_background_image"/>
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/anim_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:titleTextColor="@color/titleTextColor"
|
||||
app:layout_collapseMode="pin"
|
||||
app:popupTheme="@style/ThemeOverlay.MaterialComponents.Light" />
|
||||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:fillViewport="true"
|
||||
android:paddingBottom="@dimen/global_padding_bottom"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:backgroundTint="@color/cardColor"
|
||||
app:layout_constraintDimensionRatio="W, 4:5"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:cardCornerRadius="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/artist_backdrop_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/gradient_backdrop_background_image" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/artist_name_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="32dp"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@android:color/white"
|
||||
android:textFontWeight="900"
|
||||
android:textSize="40sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- Label and button -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp">
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="18dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Label and button -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="Most Streamed Songs"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/most_streamed_song_text_view_clickable"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:paddingEnd="16dp"
|
||||
android:text="See all"
|
||||
android:textColor="@color/subtitleTextColor"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/most_streamed_song_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="16dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="Most Streamed Songs"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="Albums"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/most_streamed_song_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"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/albums_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="8dp"
|
||||
android:text="See all"
|
||||
android:textColor="@color/subtitleTextColor"
|
||||
android:textSize="14sp" />
|
||||
android:paddingBottom="8dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/most_streamed_song_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="8dp"
|
||||
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="Albums"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/albums_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="8dp"
|
||||
android:paddingBottom="8dp" />
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -3,8 +3,7 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="20dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_progress_bar"
|
||||
|
|
@ -20,14 +19,13 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
|
||||
android:visibility="gone"
|
||||
android:paddingTop="8dp">
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="8dp">
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="20dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_progress_bar"
|
||||
|
|
@ -26,7 +25,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="8dp">
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
|
||||
<!-- Label and button -->
|
||||
<LinearLayout
|
||||
|
|
|
|||
|
|
@ -9,14 +9,13 @@
|
|||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
|
||||
android:paddingTop="20dp">
|
||||
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="8dp">
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
|
||||
<!-- Discover music -->
|
||||
<LinearLayout
|
||||
|
|
@ -40,7 +39,7 @@
|
|||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/discover_song_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="188dp"
|
||||
android:layout_height="212dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp" />
|
||||
|
|
@ -297,7 +296,7 @@
|
|||
android:paddingStart="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingBottom="24dp" />
|
||||
android:paddingBottom="8dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
|
||||
android:paddingTop="20dp">
|
||||
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
132
app/src/main/res/layout/fragment_player_bottom_sheet.xml
Normal file
132
app/src/main/res/layout/fragment_player_bottom_sheet.xml
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/player_nested_scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/cardColor"
|
||||
app:elevation="8dp">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<include
|
||||
android:id="@+id/player_header_layout"
|
||||
layout="@layout/player_header_bottom_sheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_peek_height"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/player_big_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/collapse_bottom_sheet_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingTop="20dp"
|
||||
android:text="Now playing"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/player_song_cover_view_pager"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="20dp"
|
||||
app:layout_constraintDimensionRatio="H,1:1"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/collapse_bottom_sheet_button" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/player_big_progress_bar"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="28dp"
|
||||
android:layout_marginTop="18dp"
|
||||
android:layout_marginEnd="28dp"
|
||||
android:progress="50"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_song_cover_view_pager" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_song_title_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="24dp"
|
||||
android:layout_marginTop="18dp"
|
||||
android:text="@string/label_placeholder"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_big_progress_bar" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_artist_name_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="24dp"
|
||||
android:text="@string/label_placeholder"
|
||||
android:textColor="@color/subtitleTextColor"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_song_title_label" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/button_favorite"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:background="@drawable/button_favorite_selector"
|
||||
android:checked="false"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:text=""
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_big_progress_bar" />
|
||||
|
||||
|
||||
<View style="@style/Divider"
|
||||
android:id="@+id/player_divider"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginStart="18dp"
|
||||
android:layout_marginEnd="18dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_artist_name_label"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/player_queue_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="18dp"
|
||||
android:paddingBottom="@dimen/global_padding_bottom"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_divider"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
@ -2,8 +2,7 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="20dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.paulrybitskyi.persistentsearchview.PersistentSearchView
|
||||
android:id="@+id/persistentSearchView"
|
||||
|
|
@ -100,7 +99,8 @@
|
|||
android:id="@+id/search_result_nested_scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
android:visibility="gone"
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
|
||||
<!-- Search result -->
|
||||
<LinearLayout
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="20dp">
|
||||
android:paddingTop="20dp"
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
</RelativeLayout>
|
||||
|
|
@ -2,8 +2,7 @@
|
|||
<androidx.core.widget.NestedScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="20dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -32,6 +31,6 @@
|
|||
android:layout_marginBottom="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp" />
|
||||
android:paddingBottom="@dimen/global_padding_bottom"/>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="20dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_progress_bar"
|
||||
|
|
|
|||
|
|
@ -13,16 +13,16 @@
|
|||
<ImageView
|
||||
android:id="@+id/discover_song_cover_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="172dp" />
|
||||
android:layout_height="196dp" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="172dp"
|
||||
android:layout_height="196dp"
|
||||
android:background="@drawable/gradient_discover_background_image" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="172dp">
|
||||
android:layout_height="196dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_discover_song_label"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="8dp">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="8dp">
|
||||
|
|
|
|||
18
app/src/main/res/layout/item_player_now_playing_song.xml
Normal file
18
app/src/main/res/layout/item_player_now_playing_song.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:backgroundTint="@color/cardColor"
|
||||
app:cardCornerRadius="4dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/discover_song_cover_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="?attr/selectableItemBackground"/>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
80
app/src/main/res/layout/item_player_queue_song.xml
Normal file
80
app/src/main/res/layout/item_player_queue_song.xml
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingTop="3dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingBottom="3dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="2dp"
|
||||
android:backgroundTint="@color/cardColor"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="@color/subtitleTextColor"
|
||||
card_view:cardCornerRadius="4dp"
|
||||
card_view:cardElevation="2dp"
|
||||
card_view:cardPreventCornerOverlap="false"
|
||||
card_view:cardUseCompatPadding="false">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/queue_song_cover_image_view"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="52dp" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/queue_song_title_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:text="@string/label_placeholder"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/queue_song_artist_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:paddingStart="12dp"
|
||||
android:text="@string/label_placeholder"
|
||||
android:textColor="@color/subtitleTextColor"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/queue_song_dragger_image"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:src="@drawable/ic_drag_handle"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</LinearLayout>
|
||||
87
app/src/main/res/layout/player_body_bottom_sheet.xml
Normal file
87
app/src/main/res/layout/player_body_bottom_sheet.xml
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/player_big_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/collapse_bottom_sheet_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="20dp"
|
||||
android:text="Now playing"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/player_song_cover_view_pager"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
app:layout_constraintDimensionRatio="H,1:1"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/collapse_bottom_sheet_button" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/player_big_progress_bar"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="18dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:progress="50"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_song_cover_view_pager" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_song_title_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="20dp"
|
||||
android:layout_marginTop="18dp"
|
||||
android:text="@string/label_placeholder"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_big_progress_bar" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_artist_name_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="20dp"
|
||||
android:text="@string/label_placeholder"
|
||||
android:textColor="@color/subtitleTextColor"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_song_title_label" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/button_favorite"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:background="@drawable/button_favorite_selector"
|
||||
android:checked="false"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:text=""
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_big_progress_bar" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
45
app/src/main/res/layout/player_header_bottom_sheet.xml
Normal file
45
app/src/main/res/layout/player_header_bottom_sheet.xml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_peek_height"
|
||||
android:elevation="2dp"
|
||||
android:background="@color/almostCardColor">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/player_header_button"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:src="@drawable/ic_play"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_header_song_title_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintStart_toEndOf="@+id/player_header_button"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:text="@string/label_placeholder"
|
||||
android:paddingStart="12dp"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_header_song_artist_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/open_sans_font_family"
|
||||
android:paddingStart="12dp"
|
||||
android:textColor="@color/subtitleTextColor"
|
||||
android:textSize="12sp"
|
||||
android:text="@string/label_placeholder"
|
||||
app:layout_constraintStart_toEndOf="@+id/player_header_button"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_header_song_title_label" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/nav_graph"
|
||||
app:startDestination="@id/landingFragment">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/landingFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.LandingFragment"
|
||||
android:label="fragment_landing"
|
||||
tools:layout="@layout/fragment_landing" >
|
||||
<action
|
||||
android:id="@+id/action_landingFragment_to_loginFragment"
|
||||
app:destination="@id/loginFragment"
|
||||
app:popUpTo="@id/landingFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
<action
|
||||
android:id="@+id/action_landingFragment_to_homeFragment"
|
||||
app:destination="@id/homeFragment"
|
||||
app:popUpTo="@id/landingFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
<action
|
||||
android:id="@+id/action_landingFragment_to_syncFragment"
|
||||
app:destination="@id/syncFragment"
|
||||
app:popUpTo="@id/landingFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/loginFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.LoginFragment"
|
||||
android:label="LoginFragment"
|
||||
tools:layout="@layout/fragment_login">
|
||||
<action
|
||||
android:id="@+id/action_loginFragment_to_syncFragment"
|
||||
app:destination="@id/syncFragment"
|
||||
app:popUpTo="@id/loginFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
<action
|
||||
android:id="@+id/action_loginFragment_to_homeFragment"
|
||||
app:destination="@id/homeFragment"
|
||||
app:popUpTo="@id/loginFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/syncFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.SyncFragment"
|
||||
android:label="SyncFragment"
|
||||
tools:layout="@layout/fragment_sync">
|
||||
<action
|
||||
android:id="@+id/action_syncFragment_to_homeFragment"
|
||||
app:destination="@id/homeFragment"
|
||||
app:popUpTo="@id/syncFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/homeFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.HomeFragment"
|
||||
android:label="HomeFragment"
|
||||
tools:layout="@layout/fragment_home">
|
||||
<action
|
||||
android:id="@+id/action_homeFragment_to_syncFragment"
|
||||
app:destination="@id/syncFragment" />
|
||||
<action
|
||||
android:id="@+id/action_homeFragment_to_songListPageFragment"
|
||||
app:destination="@id/songListPageFragment" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/songListPageFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.SongListPageFragment"
|
||||
android:label="SongListPageFragment"
|
||||
tools:layout="@layout/fragment_song_list_page"/>
|
||||
</navigation>
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/nav_graph">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/libraryFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.LibraryFragment"
|
||||
android:label="LibraryFragment"
|
||||
tools:layout="@layout/fragment_library">
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_artistCatalogueFragment"
|
||||
app:destination="@id/artistCatalogueFragment" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_albumCatalogueFragment"
|
||||
app:destination="@id/albumCatalogueFragment" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_genreCatalogueFragment"
|
||||
app:destination="@id/genreCatalogueFragment" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_artistPageFragment"
|
||||
app:destination="@id/artistPageFragment"/>
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_albumPageFragment"
|
||||
app:destination="@id/albumPageFragment" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_songListPageFragment"
|
||||
app:destination="@id/songListPageFragment" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/artistCatalogueFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.ArtistCatalogueFragment"
|
||||
android:label="ArtistCatalogueFragment"
|
||||
tools:layout="@layout/fragment_artist_catalogue">
|
||||
<action
|
||||
android:id="@+id/action_artistCatalogueFragment_to_artistPageFragment"
|
||||
app:destination="@id/artistPageFragment"/>
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/albumCatalogueFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.AlbumCatalogueFragment"
|
||||
android:label="AlbumCatalogueFragment"
|
||||
tools:layout="@layout/fragment_album_catalogue">
|
||||
<action
|
||||
android:id="@+id/action_albumCatalogueFragment_to_albumPageFragment"
|
||||
app:destination="@id/albumPageFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/genreCatalogueFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.GenreCatalogueFragment"
|
||||
android:label="GenreCatalogueFragment"
|
||||
tools:layout="@layout/fragment_genre_catalogue">
|
||||
<action
|
||||
android:id="@+id/action_genreCatalogueFragment_to_songListPageFragment"
|
||||
app:destination="@id/songListPageFragment" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/artistPageFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.ArtistPageFragment"
|
||||
android:label="ArtistPageFragment"
|
||||
tools:layout="@layout/fragment_artist_page">
|
||||
<action
|
||||
android:id="@+id/action_artistPageFragment_to_albumPageFragment"
|
||||
app:destination="@id/albumPageFragment" />
|
||||
<action
|
||||
android:id="@+id/action_artistPageFragment_to_songListPageFragment"
|
||||
app:destination="@id/songListPageFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/albumPageFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.AlbumPageFragment"
|
||||
android:label="AlbumPageFragment"
|
||||
tools:layout="@layout/fragment_album_page"/>
|
||||
<fragment
|
||||
android:id="@+id/songListPageFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.SongListPageFragment"
|
||||
android:label="SongListPageFragment"
|
||||
tools:layout="@layout/fragment_song_list_page"/>
|
||||
</navigation>
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/nav_graph">
|
||||
|
||||
|
||||
<fragment
|
||||
android:id="@+id/searchFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.SearchFragment"
|
||||
android:label="SearchFragment"
|
||||
tools:layout="@layout/fragment_search">
|
||||
<action
|
||||
android:id="@+id/action_searchFragment_to_filterFragment"
|
||||
app:destination="@id/filterFragment" />
|
||||
<action
|
||||
android:id="@+id/action_searchFragment_to_artistPageFragment"
|
||||
app:destination="@id/artistPageFragment"/>
|
||||
<action
|
||||
android:id="@+id/action_searchFragment_to_albumPageFragment"
|
||||
app:destination="@id/albumPageFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/filterFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.FilterFragment"
|
||||
android:label="FilterFragment"
|
||||
tools:layout="@layout/fragment_filter" />
|
||||
|
||||
|
||||
<fragment
|
||||
android:id="@+id/artistPageFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.ArtistPageFragment"
|
||||
android:label="ArtistPageFragment"
|
||||
tools:layout="@layout/fragment_artist_page">
|
||||
<action
|
||||
android:id="@+id/action_artistPageFragment_to_albumPageFragment"
|
||||
app:destination="@id/albumPageFragment" />
|
||||
<action
|
||||
android:id="@+id/action_artistPageFragment_to_songListPageFragment"
|
||||
app:destination="@id/songListPageFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/albumPageFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.AlbumPageFragment"
|
||||
android:label="AlbumPageFragment"
|
||||
tools:layout="@layout/fragment_album_page"/>
|
||||
<fragment
|
||||
android:id="@+id/songListPageFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.SongListPageFragment"
|
||||
android:label="SongListPageFragment"
|
||||
tools:layout="@layout/fragment_song_list_page"/>
|
||||
</navigation>
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/nav_graph">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/settingsFragment"
|
||||
android:name="com.cappielloantonio.play.ui.fragment.SettingsFragment"
|
||||
android:label="SettingsFragment"
|
||||
tools:layout="@layout/fragment_settings"/>
|
||||
</navigation>
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
<color name="navigationDrawerColor">#121211</color>
|
||||
|
||||
<color name="cardColor">#1D1D1D</color>
|
||||
<color name="almostCardColor">#1D1D1C</color>
|
||||
|
||||
<color name="titleTextColor">#DADADA</color>
|
||||
<color name="subtitleTextColor">#9B9B9B</color>
|
||||
|
|
|
|||
|
|
@ -22,4 +22,10 @@
|
|||
<item name="android:windowMinWidthMajor">82%</item>
|
||||
<item name="android:windowMinWidthMinor">82%</item>
|
||||
</style>
|
||||
|
||||
<style name="Divider">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">1dp</item>
|
||||
<item name="android:background">@color/dividerColor</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
<color name="navigationDrawerColor">#FFFFFF</color>
|
||||
|
||||
<color name="cardColor">#FFFFFF</color>
|
||||
<color name="almostCardColor">#FFFFFE</color>
|
||||
|
||||
<color name="titleTextColor">#252525</color>
|
||||
<color name="subtitleTextColor">#646464</color>
|
||||
|
|
@ -41,4 +42,6 @@
|
|||
<color name="chipBorderColor">#AFAFAF</color>
|
||||
<color name="chipSelectedBackgroundColor">#EBEBEB</color>
|
||||
<color name="chipUnelectedBackgroundColor">#FFFFFF</color>
|
||||
|
||||
<color name="white">#FFFFFF</color>
|
||||
</resources>
|
||||
|
|
@ -5,4 +5,11 @@
|
|||
<dimen name="nav_header_vertical_spacing">8dp</dimen>
|
||||
<dimen name="nav_header_height">176dp</dimen>
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
|
||||
<dimen name="appbar_header_height">384dp</dimen>
|
||||
<dimen name="activity_margin_content">24dp</dimen>
|
||||
|
||||
<dimen name="bottom_sheet_peek_height">56dp</dimen>
|
||||
|
||||
<dimen name="global_padding_bottom">64dp</dimen>
|
||||
</resources>
|
||||
|
|
@ -21,4 +21,10 @@
|
|||
<item name="android:windowMinWidthMajor">82%</item>
|
||||
<item name="android:windowMinWidthMinor">82%</item>
|
||||
</style>
|
||||
|
||||
<style name="Divider">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">1dp</item>
|
||||
<item name="android:background">@color/dividerColor</item>
|
||||
</style>
|
||||
</resources>
|
||||
Loading…
Add table
Add a link
Reference in a new issue