mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2026-05-16 04:52:39 +02:00
Library continuation, disable auto backup ask, minor tweaks.
This commit is contained in:
@@ -951,7 +951,7 @@ class Settings : FragmentedStorageFileJson() {
|
||||
class Backup {
|
||||
@Serializable(with = OffsetDateTimeSerializer::class)
|
||||
var lastAutoBackupTime: OffsetDateTime = OffsetDateTime.MIN;
|
||||
var didAskAutoBackup: Boolean = false;
|
||||
var didAskAutoBackup: Boolean = true;
|
||||
var autoBackupPassword: String? = null;
|
||||
fun shouldAutomaticBackup() = autoBackupPassword != null;
|
||||
|
||||
|
||||
+3
-2
@@ -32,6 +32,7 @@ import com.futo.platformplayer.images.GlideHelper.Companion.crossfade
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.states.Album
|
||||
import com.futo.platformplayer.states.Artist
|
||||
import com.futo.platformplayer.states.ArtistOrdering
|
||||
import com.futo.platformplayer.states.StateLibrary
|
||||
import com.futo.platformplayer.stores.FragmentedStorage
|
||||
import com.futo.platformplayer.stores.StringStorage
|
||||
@@ -82,7 +83,7 @@ class LibraryArtistsFragment : MainFragment() {
|
||||
constructor(fragment: LibraryArtistsFragment, inflater: LayoutInflater) : super(fragment, inflater)
|
||||
|
||||
fun onShown() {
|
||||
val intialArtists = StateLibrary.instance.getArtists();
|
||||
val intialArtists = StateLibrary.instance.getArtists(ArtistOrdering.Alphabethic);
|
||||
Logger.i(TAG, "Initial album count: " + intialArtists.size);
|
||||
|
||||
setPager(AdhocPager<Artist>({ listOf(); }, intialArtists));
|
||||
@@ -91,7 +92,7 @@ class LibraryArtistsFragment : MainFragment() {
|
||||
override fun reload() {
|
||||
try {
|
||||
setLoading(true);
|
||||
val intialArtists = StateLibrary.instance.getArtists();
|
||||
val intialArtists = StateLibrary.instance.getArtists(ArtistOrdering.Alphabethic);
|
||||
Logger.i(TAG, "Initial album count: " + intialArtists.size);
|
||||
|
||||
setPager(AdhocPager<Artist>({ listOf(); }, intialArtists));
|
||||
|
||||
+132
-33
@@ -7,16 +7,37 @@ import android.provider.MediaStore
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.UIDialogs
|
||||
import com.futo.platformplayer.activities.MainActivity
|
||||
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
||||
import com.futo.platformplayer.dp
|
||||
import com.futo.platformplayer.states.Album
|
||||
import com.futo.platformplayer.states.Artist
|
||||
import com.futo.platformplayer.states.ArtistOrdering
|
||||
import com.futo.platformplayer.states.FileEntry
|
||||
import com.futo.platformplayer.states.StateApp
|
||||
import com.futo.platformplayer.states.StateLibrary
|
||||
import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny
|
||||
import com.futo.platformplayer.views.AnyInsertedAdapterView
|
||||
import com.futo.platformplayer.views.AnyInsertedAdapterView.Companion.asAnyWithTop
|
||||
import com.futo.platformplayer.views.AnyInsertedAdapterView.Companion.asAnyWithViews
|
||||
import com.futo.platformplayer.views.LibrarySection
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
import com.futo.platformplayer.views.adapters.InsertedViewAdapter
|
||||
import com.futo.platformplayer.views.adapters.viewholders.AlbumTileViewHolder
|
||||
import com.futo.platformplayer.views.adapters.viewholders.ArtistTileViewHolder
|
||||
import com.futo.platformplayer.views.adapters.viewholders.LocalVideoTileViewHolder
|
||||
import com.futo.platformplayer.views.buttons.BigButton
|
||||
|
||||
|
||||
@@ -117,13 +138,17 @@ class LibraryFragment : MainFragment() {
|
||||
class FragView: ConstraintLayout {
|
||||
val fragment: LibraryFragment;
|
||||
|
||||
var buttonArtists: BigButton;
|
||||
var buttonAlbums: BigButton;
|
||||
var buttonVideos: BigButton;
|
||||
var buttonPlaylists: BigButton;
|
||||
var buttonFiles: BigButton;
|
||||
var sectionArtists: LibrarySection;
|
||||
var sectionAlbums: LibrarySection;
|
||||
var sectionVideos: LibrarySection;
|
||||
var sectionFiles: LibrarySection;
|
||||
//var buttonFiles: BigButton;
|
||||
|
||||
var metaInfo: TextView;
|
||||
val recycler: RecyclerView;
|
||||
|
||||
val adapterFiles: AnyInsertedAdapterView<FileEntry,LibraryFilesFragment.FileViewHolder>;
|
||||
|
||||
//var metaInfo: TextView;
|
||||
|
||||
var allowMusic: Boolean = false;
|
||||
var allowVideo: Boolean = false;
|
||||
@@ -131,61 +156,135 @@ class LibraryFragment : MainFragment() {
|
||||
constructor(fragment: LibraryFragment, allowMusic: Boolean?, allowVideo: Boolean?) : super(fragment.requireContext()) {
|
||||
inflate(context, R.layout.fragview_library, this);
|
||||
this.fragment = fragment;
|
||||
buttonArtists = findViewById<BigButton>(R.id.button_artists);
|
||||
buttonAlbums = findViewById<BigButton>(R.id.button_albums);
|
||||
buttonVideos = findViewById<BigButton>(R.id.button_videos);
|
||||
buttonPlaylists = findViewById<BigButton>(R.id.button_playlists);
|
||||
buttonFiles = findViewById<BigButton>(R.id.button_files);
|
||||
metaInfo = findViewById(R.id.meta_info);
|
||||
recycler = findViewById(R.id.recycler);
|
||||
sectionArtists = LibrarySection(context)//findViewById<LibrarySection>(R.id.section_artists);
|
||||
sectionArtists.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 155.dp(resources)).apply {
|
||||
this.setMargins(0,10.dp(resources), 0, 0);
|
||||
}
|
||||
sectionAlbums = LibrarySection(context)//findViewById(R.id.section_albums);
|
||||
sectionAlbums.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 185.dp(resources)).apply {
|
||||
this.setMargins(0,0, 0, 0);
|
||||
}
|
||||
sectionVideos = LibrarySection(context)//findViewById(R.id.section_videos);
|
||||
sectionVideos.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 170.dp(resources)).apply {
|
||||
this.setMargins(0,0, 0, 0);
|
||||
}
|
||||
sectionFiles = LibrarySection(context)//findViewById(R.id.section_videos);
|
||||
sectionFiles.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40.dp(resources)).apply {
|
||||
this.setMargins(0,0, 0, 0);
|
||||
}
|
||||
sectionFiles.setSection("Directories") {
|
||||
StateLibrary.instance.addFileDirectory {
|
||||
reloadFiles();
|
||||
}
|
||||
}
|
||||
sectionFiles.setNavIcon(R.drawable.ic_add);
|
||||
//buttonFiles = findViewById<BigButton>(R.id.button_files);
|
||||
//metaInfo = findViewById(R.id.meta_info);
|
||||
|
||||
this.allowMusic = allowMusic ?: false;
|
||||
this.allowVideo = allowVideo ?: false;
|
||||
|
||||
buttonArtists.onClick.subscribe {
|
||||
sectionArtists.setSection("Artists", {
|
||||
if(this.allowMusic)
|
||||
fragment.navigate<LibraryArtistsFragment>();
|
||||
else
|
||||
fragment.requestPermissionMusic();
|
||||
}
|
||||
buttonAlbums.onClick.subscribe {
|
||||
});
|
||||
val adapterArtists = sectionArtists.getAnyAdapter<Artist, ArtistTileViewHolder>({
|
||||
it.onClick.subscribe {
|
||||
if(it != null)
|
||||
fragment.navigate<LibraryArtistFragment>(it);
|
||||
}
|
||||
});
|
||||
val artists = StateLibrary.instance.getArtists(ArtistOrdering.TrackCount);
|
||||
adapterArtists.setData(artists);
|
||||
|
||||
sectionAlbums.setSection("Albums", {
|
||||
if(this.allowMusic)
|
||||
fragment.navigate<LibraryAlbumsFragment>();
|
||||
else
|
||||
fragment.requestPermissionMusic();
|
||||
}
|
||||
buttonVideos.onClick.subscribe {
|
||||
});
|
||||
val adapterAlbums = sectionAlbums.getAnyAdapter<Album, AlbumTileViewHolder>({
|
||||
it.onClick.subscribe {
|
||||
if(it != null)
|
||||
fragment.navigate<LibraryAlbumFragment>(it);
|
||||
}
|
||||
});
|
||||
val albums = StateLibrary.instance.getAlbums();
|
||||
adapterAlbums.setData(albums);
|
||||
|
||||
|
||||
sectionVideos.setSection("Videos", {
|
||||
if(this.allowVideo)
|
||||
fragment.navigate<LibraryVideosFragment>();
|
||||
else
|
||||
fragment.requestPermissionVideo();
|
||||
}
|
||||
buttonPlaylists.onClick.subscribe {
|
||||
fragment.navigate<PlaylistsFragment>();
|
||||
}
|
||||
});
|
||||
val adapterVideos = sectionVideos.getAnyAdapter<IPlatformVideo, LocalVideoTileViewHolder>({
|
||||
it.onClick.subscribe {
|
||||
if(it != null)
|
||||
fragment.navigate<VideoDetailFragment>(it);
|
||||
}
|
||||
});
|
||||
val videos = StateLibrary.instance.getRecentVideos(null, 20);
|
||||
adapterVideos.setData(videos);
|
||||
|
||||
adapterFiles = recycler.asAnyWithViews<FileEntry, LibraryFilesFragment.FileViewHolder>(
|
||||
arrayListOf(
|
||||
sectionArtists,
|
||||
sectionAlbums,
|
||||
sectionVideos,
|
||||
sectionFiles
|
||||
), arrayListOf(), RecyclerView.VERTICAL, false, {
|
||||
it.onClick.subscribe {
|
||||
if(it != null)
|
||||
fragment.navigate<LibraryFilesFragment>(it);
|
||||
}
|
||||
it.onDelete.subscribe {
|
||||
if(it != null) {
|
||||
StateLibrary.instance.deleteFileDirectory(it.path);
|
||||
reloadFiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
reloadFiles();
|
||||
|
||||
|
||||
/*
|
||||
buttonFiles.onClick.subscribe {
|
||||
fragment.navigate<LibraryFilesFragment>()
|
||||
}
|
||||
} */
|
||||
//buttonFiles.setButtonEnabled(false);
|
||||
setMusicPermissions(allowMusic ?: false);
|
||||
setVideoPermissions(allowVideo ?: false);
|
||||
}
|
||||
|
||||
fun reloadFiles() {
|
||||
val files = StateLibrary.instance.getFileDirectories();
|
||||
adapterFiles.setData(files);
|
||||
}
|
||||
|
||||
|
||||
fun setMusicPermissions(access: Boolean) {
|
||||
allowMusic = access;
|
||||
buttonAlbums.setButtonEnabled(access);
|
||||
buttonArtists.setButtonEnabled(access);
|
||||
metaInfo.text = listOf(
|
||||
if(!allowMusic) "You did not give access to local music, so these options are disabled" else null,
|
||||
if(!allowVideo) "You did not give access to local videos, so these options are disabled" else null
|
||||
).filterNotNull().joinToString("\n");
|
||||
sectionAlbums.setContentEmptyMessage(R.drawable.ic_library, "No mediastore permissions");
|
||||
sectionArtists.setContentEmptyMessage(R.drawable.ic_library, "No mediastore permissions");
|
||||
//buttonArtists.setButtonEnabled(access);
|
||||
//metaInfo.text = listOf(
|
||||
// if(!allowMusic) "You did not give access to local music, so these options are disabled" else null,
|
||||
// if(!allowVideo) "You did not give access to local videos, so these options are disabled" else null
|
||||
//).filterNotNull().joinToString("\n");
|
||||
}
|
||||
fun setVideoPermissions(access: Boolean) {
|
||||
allowVideo = access;
|
||||
buttonVideos.setButtonEnabled(access);
|
||||
metaInfo.text = listOf(
|
||||
if(!allowMusic) "You did not give access to local music, so these options are disabled" else null,
|
||||
if(!allowVideo) "You did not give access to local videos, so these options are disabled" else null
|
||||
).filterNotNull().joinToString("\n");
|
||||
sectionVideos.setContentEmptyMessage(R.drawable.ic_library, "No video permissions");
|
||||
//metaInfo.text = listOf(
|
||||
// if(!allowMusic) "You did not give access to local music, so these options are disabled" else null,
|
||||
// if(!allowVideo) "You did not give access to local videos, so these options are disabled" else null
|
||||
//).filterNotNull().joinToString("\n");
|
||||
}
|
||||
|
||||
fun onShown() {
|
||||
|
||||
@@ -593,7 +593,9 @@ class StateApp {
|
||||
scheduleBackgroundWork(context, interval != 0, interval);
|
||||
|
||||
Logger.i(TAG, "MainApp Started: Initialize [AutoBackup]");
|
||||
Settings.instance.backup.didAskAutoBackup = true; //Some users have issues with it
|
||||
if(!Settings.instance.backup.didAskAutoBackup && !Settings.instance.backup.shouldAutomaticBackup()) {
|
||||
/*
|
||||
StateAnnouncement.instance.registerAnnouncement("backup", "Set Automatic Backup", "Configure daily backups of your data to restore in case of catastrophic failure.", AnnouncementType.SESSION, null, null, "Configure", {
|
||||
if(context is IWithResultLauncher && !Settings.instance.storage.isStorageMainValid(context)) {
|
||||
UIDialogs.toast("Missing general directory");
|
||||
@@ -610,6 +612,7 @@ class StateApp {
|
||||
Settings.instance.backup.didAskAutoBackup = true;
|
||||
Settings.instance.save();
|
||||
});
|
||||
*/
|
||||
}
|
||||
else if(Settings.instance.backup.didAskAutoBackup && Settings.instance.backup.shouldAutomaticBackup() && !Settings.instance.storage.isStorageMainValid(context)) {
|
||||
if(context is IWithResultLauncher) {
|
||||
|
||||
@@ -100,8 +100,8 @@ class StateLibrary {
|
||||
return Album.getAlbum(id);
|
||||
}
|
||||
|
||||
fun getArtists(): List<Artist> {
|
||||
return Artist.getArtists();
|
||||
fun getArtists(ordering: ArtistOrdering): List<Artist> {
|
||||
return Artist.getArtists(ordering);
|
||||
}
|
||||
fun getArtist(str: String): Artist? {
|
||||
val idLong = str.toLongOrNull();
|
||||
@@ -114,8 +114,9 @@ class StateLibrary {
|
||||
}
|
||||
|
||||
fun getVideos(buckets: List<String>? = null): IPager<IPlatformContent> {
|
||||
var query = if(buckets != null) "${MediaStore.Video.Media.BUCKET_DISPLAY_NAME} IN " + "(" + buckets.map { "'${it}'" }.joinToString(",") + ")" else null;
|
||||
val cursor = StateApp.instance.contextOrNull?.contentResolver?.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, PROJECTION_VIDEO,
|
||||
if(buckets != null) "${MediaStore.Video.Media.BUCKET_DISPLAY_NAME} IN " + "(" + buckets.map { "'${it}'" }.joinToString(",") + ")" else null,
|
||||
query,
|
||||
null,
|
||||
MediaStore.Video.Media.DATE_ADDED + " DESC") ?: return EmptyPager();
|
||||
cursor.moveToFirst();
|
||||
@@ -134,6 +135,16 @@ class StateLibrary {
|
||||
return@AdhocPager list;
|
||||
}, list);
|
||||
}
|
||||
fun getRecentVideos(buckets: List<String>? = null, count: Int = 20): List<IPlatformVideo> {
|
||||
val videoPager = getVideos(buckets);
|
||||
val items = mutableListOf<IPlatformVideo>();
|
||||
while(videoPager.getResults().size > 0 && items.size < count) {
|
||||
items.addAll(videoPager.getResults().filter { it is IPlatformVideo }.map { it as IPlatformVideo });
|
||||
if(videoPager.hasMorePages())
|
||||
videoPager.nextPage();
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private var _cacheBucketNames: List<Bucket>? = null;
|
||||
fun getVideoBucketNames(): List<Bucket> {
|
||||
@@ -363,6 +374,12 @@ class StateLibrary {
|
||||
|
||||
class Bucket(val id: Long, val name: String);
|
||||
|
||||
|
||||
enum class ArtistOrdering {
|
||||
Alphabethic,
|
||||
TrackCount,
|
||||
AlbumCount
|
||||
}
|
||||
class Artist {
|
||||
val id: String;
|
||||
val name: String;
|
||||
@@ -424,9 +441,18 @@ class Artist {
|
||||
return null;
|
||||
return Artist.fromCursor(cursor);
|
||||
}
|
||||
fun getArtists(): List<Artist> {
|
||||
val cursor = StateApp.instance.contextOrNull?.contentResolver?.query(Artists.EXTERNAL_CONTENT_URI, PROJECTION, null, null,
|
||||
Artists.ARTIST + " ASC") ?: return listOf();
|
||||
fun getArtists(ordering: ArtistOrdering = ArtistOrdering.Alphabethic): List<Artist> {
|
||||
val ordering = when(ordering) {
|
||||
ArtistOrdering.Alphabethic -> Artists.ARTIST + " ASC";
|
||||
ArtistOrdering.AlbumCount -> Artists.NUMBER_OF_ALBUMS + " DESC";
|
||||
ArtistOrdering.TrackCount -> Artists.NUMBER_OF_TRACKS + " DESC";
|
||||
else -> null
|
||||
}
|
||||
|
||||
val cursor = StateApp.instance.contextOrNull?.contentResolver?.query(Artists.EXTERNAL_CONTENT_URI, PROJECTION,
|
||||
null,
|
||||
null,
|
||||
ordering) ?: return listOf();
|
||||
cursor.moveToFirst();
|
||||
val list = mutableListOf<Artist>()
|
||||
while(!cursor.isAfterLast) {
|
||||
|
||||
@@ -72,9 +72,9 @@ class AnyInsertedAdapterView<I, T>(view: RecyclerView, adapter: BaseAnyAdapter<I
|
||||
= this.asAnyWithViews(arrayListOf(view), arrayListOf(), orientation, reversed, onCreate);
|
||||
inline fun<I, reified T : AnyAdapter.AnyViewHolder<I>> RecyclerView.asAnyWithViews(prepend: ArrayList<View> = arrayListOf(), append: ArrayList<View> = arrayListOf(), orientation: Int = RecyclerView.VERTICAL, reversed: Boolean = false, noinline onCreate: ((T)->Unit)? = null) : AnyInsertedAdapterView<I, T> {
|
||||
for(view in prepend)
|
||||
(view.parent as ViewGroup).removeView(view);
|
||||
(view.parent as ViewGroup?)?.removeView(view);
|
||||
for(view in append)
|
||||
(view.parent as ViewGroup).removeView(view);
|
||||
(view.parent as ViewGroup?)?.removeView(view);
|
||||
return AnyInsertedAdapterView(this, AnyInsertedAdapter.create(prepend, append, onCreate), orientation, reversed);
|
||||
}
|
||||
inline fun<I, reified T : AnyAdapter.AnyViewHolder<I>> RecyclerView.asAnyWithViews(list: ArrayList<I>, prepend: ArrayList<View> = arrayListOf(), append: ArrayList<View> = arrayListOf(), orientation: Int = RecyclerView.VERTICAL, reversed: Boolean = false, noinline onCreate: ((T)->Unit)? = null) : AnyInsertedAdapterView<I, T> {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.futo.platformplayer.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout.GONE
|
||||
import androidx.constraintlayout.widget.ConstraintLayout.inflate
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter.AnyViewHolder
|
||||
import com.google.android.material.imageview.ShapeableImageView
|
||||
|
||||
class LibrarySection: ConstraintLayout {
|
||||
val textName: TextView;
|
||||
val imageNavigate: ImageView;
|
||||
val recycler: RecyclerView;
|
||||
|
||||
|
||||
constructor(context: Context, attr: AttributeSet? = null) : super(context, attr) {
|
||||
inflate(context, R.layout.view_library_section, this);
|
||||
textName = findViewById(R.id.text_label)
|
||||
imageNavigate = findViewById(R.id.image_nav)
|
||||
recycler = findViewById(R.id.recycler_collection);
|
||||
|
||||
}
|
||||
|
||||
fun setNavIcon(resId: Int) {
|
||||
imageNavigate.setImageResource(resId);
|
||||
}
|
||||
|
||||
fun setContentEmptyMessage(icon: Int, msg: String) {
|
||||
|
||||
}
|
||||
inline fun <T, reified V: AnyViewHolder<T>> getAnyAdapter(noinline onCreate: ((V)->Unit)? = null, orientation: Int = RecyclerView.HORIZONTAL): AnyAdapterView<T, V> {
|
||||
return recycler.asAny<T, V>(orientation, false, onCreate);
|
||||
}
|
||||
|
||||
inline fun setSection(title: String, crossinline onOpen: (()->Unit)) {
|
||||
textName.text = title;
|
||||
imageNavigate.setOnClickListener { onOpen.invoke() };
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.futo.platformplayer.views.adapters.viewholders
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.states.Album
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
|
||||
|
||||
class AlbumTileViewHolder(val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<Album>(
|
||||
LayoutInflater.from(_viewGroup.context).inflate(
|
||||
R.layout.list_album_tile,
|
||||
_viewGroup, false)) {
|
||||
|
||||
val onClick = Event1<Album?>();
|
||||
|
||||
protected var _album: Album? = null;
|
||||
protected val _imageThumbnail: ImageView
|
||||
protected val _textName: TextView
|
||||
protected val _textMetadata: TextView
|
||||
|
||||
init {
|
||||
_imageThumbnail = _view.findViewById(R.id.image_thumbnail);
|
||||
_textName = _view.findViewById(R.id.text_name);
|
||||
_textMetadata = _view.findViewById(R.id.text_metadata);
|
||||
|
||||
_view.setOnClickListener { onClick.emit(_album) };
|
||||
}
|
||||
|
||||
|
||||
override fun bind(album: Album) {
|
||||
_album = album;
|
||||
_imageThumbnail?.let {
|
||||
if (album.thumbnail != null)
|
||||
Glide.with(it)
|
||||
.load(album.thumbnail)
|
||||
.placeholder(R.drawable.unknown_music)
|
||||
.into(it)
|
||||
else
|
||||
Glide.with(it).load(R.drawable.unknown_music).into(it);
|
||||
};
|
||||
|
||||
_textName.text = album.name;
|
||||
_textMetadata.text = album.artist ?: "";
|
||||
}
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.futo.platformplayer.views.adapters.viewholders
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.states.Album
|
||||
import com.futo.platformplayer.states.Artist
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
|
||||
|
||||
class ArtistTileViewHolder(val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<Artist>(
|
||||
LayoutInflater.from(_viewGroup.context).inflate(
|
||||
R.layout.list_artist_tile,
|
||||
_viewGroup, false)) {
|
||||
|
||||
val onClick = Event1<Artist?>();
|
||||
|
||||
protected var _artist: Artist? = null;
|
||||
protected val _imageThumbnail: ImageView
|
||||
protected val _textName: TextView
|
||||
protected val _textMetadata: TextView
|
||||
|
||||
init {
|
||||
_imageThumbnail = _view.findViewById(R.id.image_thumbnail);
|
||||
_textName = _view.findViewById(R.id.text_name);
|
||||
_textMetadata = _view.findViewById(R.id.text_metadata);
|
||||
|
||||
_view.setOnClickListener { onClick.emit(_artist) };
|
||||
}
|
||||
|
||||
|
||||
override fun bind(artist: Artist) {
|
||||
_artist = artist;
|
||||
_imageThumbnail?.let {
|
||||
if (artist.thumbnail != null)
|
||||
Glide.with(it)
|
||||
.load(artist.thumbnail)
|
||||
.placeholder(R.drawable.unknown_music)
|
||||
.into(it)
|
||||
else
|
||||
Glide.with(it).load(R.drawable.unknown_music).into(it);
|
||||
};
|
||||
|
||||
_textName.text = artist.name;
|
||||
_textMetadata.text = ""// "${artist.countTracks} tracks";
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.futo.platformplayer.views.adapters.viewholders
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.bumptech.glide.Glide
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.states.Album
|
||||
import com.futo.platformplayer.states.Artist
|
||||
import com.futo.platformplayer.toHumanNowDiffString
|
||||
import com.futo.platformplayer.toHumanTime
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
import com.google.android.material.imageview.ShapeableImageView
|
||||
|
||||
|
||||
class LocalVideoTileViewHolder(val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<IPlatformVideo>(
|
||||
LayoutInflater.from(_viewGroup.context).inflate(
|
||||
R.layout.list_video_thumbnail_tile,
|
||||
_viewGroup, false)) {
|
||||
|
||||
val onClick = Event1<IPlatformVideo?>();
|
||||
|
||||
protected var _content: IPlatformVideo? = null;
|
||||
protected val _imageThumbnail: ShapeableImageView
|
||||
protected val _textDuration: TextView;
|
||||
protected val _textName: TextView
|
||||
protected val _textMetadata: TextView
|
||||
|
||||
init {
|
||||
_imageThumbnail = _view.findViewById(R.id.image_video_thumbnail);
|
||||
_textDuration = _view.findViewById(R.id.thumbnail_duration);
|
||||
_textName = _view.findViewById(R.id.text_video_name);
|
||||
_textMetadata = _view.findViewById(R.id.text_video_metadata);
|
||||
|
||||
_view.setOnClickListener { onClick.emit(_content) };
|
||||
}
|
||||
|
||||
|
||||
override fun bind(content: IPlatformVideo) {
|
||||
_content = content;
|
||||
_imageThumbnail?.let {
|
||||
if (content.thumbnails.getHQThumbnail() != null)
|
||||
Glide.with(it)
|
||||
.load(content.thumbnails.getHQThumbnail())
|
||||
.placeholder(R.drawable.unknown_music)
|
||||
.into(it)
|
||||
else
|
||||
Glide.with(it).load(R.drawable.unknown_music).into(it);
|
||||
};
|
||||
|
||||
_textName.text = content.name;
|
||||
_textMetadata.text = content.datetime?.toHumanNowDiffString();
|
||||
_textDuration.text = content.duration.toHumanTime(false) + " ago";
|
||||
_textDuration.isVisible = content.duration > 0;
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
@@ -9,22 +9,31 @@
|
||||
android:background="@drawable/bottom_menu_border"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
<!--
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_artists"
|
||||
<com.futo.platformplayer.views.LibrarySection
|
||||
android:id="@+id/section_artists"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:buttonIcon="@drawable/ic_creators"
|
||||
app:buttonSubText="All artists known on this phone"
|
||||
app:buttonText="Artists"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
android:layout_height="165dp" />
|
||||
<com.futo.platformplayer.views.LibrarySection
|
||||
android:id="@+id/section_albums"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="190dp" />
|
||||
<com.futo.platformplayer.views.LibrarySection
|
||||
android:id="@+id/section_videos"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_height="180dp" />
|
||||
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_albums"
|
||||
android:layout_width="match_parent"
|
||||
@@ -34,7 +43,8 @@
|
||||
app:buttonText="Albums"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
android:layout_marginBottom="8dp" /> -->
|
||||
<!--
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_playlists"
|
||||
android:layout_width="match_parent"
|
||||
@@ -54,7 +64,8 @@
|
||||
app:buttonSubText="All local videos on this phone"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
android:layout_marginBottom="8dp" /> -->
|
||||
<!--
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_files"
|
||||
android:layout_width="match_parent"
|
||||
@@ -62,6 +73,7 @@
|
||||
app:buttonIcon="@drawable/ic_gallery"
|
||||
app:buttonText="Files"
|
||||
app:buttonSubText="Browse files on your phone"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
@@ -82,5 +94,6 @@
|
||||
android:text=""
|
||||
android:textColor="#AAAAAA" />
|
||||
</LinearLayout>
|
||||
-->
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/image_thumbnail"
|
||||
android:layout_height="86dp"
|
||||
android:layout_width="86dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_4dp"
|
||||
app:srcCompat="@drawable/unknown_music"
|
||||
android:background="@drawable/video_thumbnail_outline"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_medium"
|
||||
tools:text="The Beetles"
|
||||
android:maxLines="2"
|
||||
app:layout_constraintLeft_toRightOf="@id/image_thumbnail"
|
||||
app:layout_constraintTop_toBottomOf="@id/image_thumbnail"
|
||||
app:layout_constraintLeft_toLeftOf="@id/image_thumbnail"
|
||||
app:layout_constraintRight_toRightOf="@id/image_thumbnail"
|
||||
android:layout_marginTop="5dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_metadata"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#75FFFFFF"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
tools:text="3 videos"
|
||||
android:maxLines="2"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_name"
|
||||
app:layout_constraintLeft_toLeftOf="@id/text_name"
|
||||
app:layout_constraintRight_toRightOf="@id/text_name" />
|
||||
|
||||
<!--
|
||||
<ImageButton
|
||||
android:id="@+id/button_play"
|
||||
android:layout_width="34dp"
|
||||
android:layout_height="34dp"
|
||||
app:srcCompat="@drawable/ic_play_white_nopad"
|
||||
android:scaleType="fitCenter"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_trash"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginEnd="10dp"/> -->
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -6,10 +6,14 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true">
|
||||
android:clickable="true"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingTop="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
@@ -19,8 +23,8 @@
|
||||
android:textSize="13dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
tools:text="Legendary grant recipient: Marvin Wißfeld Very Long Title That is Long"
|
||||
android:maxLines="2"
|
||||
tools:text="Example Artist"
|
||||
android:maxLines="1"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
@@ -55,4 +59,12 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginEnd="10dp"/> -->
|
||||
|
||||
<View
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="#181818" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="86dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/image_thumbnail"
|
||||
android:layout_height="66dp"
|
||||
android:layout_width="66dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_33dp"
|
||||
app:srcCompat="@drawable/unknown_music"
|
||||
android:background="@drawable/video_thumbnail_outline"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_medium"
|
||||
android:textAlignment="center"
|
||||
tools:text="The Beetles"
|
||||
android:maxLines="2"
|
||||
app:layout_constraintTop_toBottomOf="@id/image_thumbnail"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginTop="7dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_metadata"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#75FFFFFF"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:textAlignment="center"
|
||||
tools:text="3 videos"
|
||||
android:maxLines="2"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_name"
|
||||
app:layout_constraintLeft_toLeftOf="@id/text_name"
|
||||
app:layout_constraintRight_toRightOf="@id/text_name" />
|
||||
|
||||
<!--
|
||||
<ImageButton
|
||||
android:id="@+id/button_play"
|
||||
android:layout_width="34dp"
|
||||
android:layout_height="34dp"
|
||||
app:srcCompat="@drawable/ic_play_white_nopad"
|
||||
android:scaleType="fitCenter"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_trash"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginEnd="10dp"/> -->
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,113 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="160dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:orientation="vertical">
|
||||
<FrameLayout
|
||||
android:id="@+id/player_container"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="66dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/image_video_thumbnail"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="66dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:contentDescription="@string/thumbnail"
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_4dp"
|
||||
app:srcCompat="@drawable/placeholder_video_thumbnail"
|
||||
android:background="@drawable/video_thumbnail_outline" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/thumbnail_duration_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_gravity="end"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:paddingTop="0dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:background="@drawable/background_thumbnail_duration">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/thumbnail_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:includeFontPadding="false"
|
||||
android:paddingLeft="2dp"
|
||||
android:paddingRight="2dp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12dp"
|
||||
tools:text="0:00"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="normal" />
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="70dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/player_container"
|
||||
app:layout_constraintLeft_toLeftOf="@id/player_container"
|
||||
app:layout_constraintRight_toRightOf="@id/player_container"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_video_name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="2dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="11dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
tools:text="Legendary grant recipient: Marvin Wißfeld of MicroG Very loong title fff"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_video_metadata"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="1"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="10dp"
|
||||
android:textColor="@color/gray_e0"
|
||||
android:fontFamily="@font/inter_extra_light"
|
||||
tools:text="57K views • 1 day ago"
|
||||
app:layout_constraintLeft_toLeftOf="@id/text_video_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_video_name"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginStart="0dp"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textSize="20sp"
|
||||
android:text="Albums" />
|
||||
<ImageView
|
||||
android:id="@+id/image_nav"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_marginRight="10dp"
|
||||
app:layout_constraintTop_toTopOf="@id/text_label"
|
||||
app:layout_constraintBottom_toBottomOf="@id/text_label"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
|
||||
android:src="@drawable/ic_arrow_right" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_collection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_label"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
<!--
|
||||
<ImageButton
|
||||
android:id="@+id/button_play"
|
||||
android:layout_width="34dp"
|
||||
android:layout_height="34dp"
|
||||
app:srcCompat="@drawable/ic_play_white_nopad"
|
||||
android:scaleType="fitCenter"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_trash"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginEnd="10dp"/> -->
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -23,6 +23,14 @@
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">16dp</item>
|
||||
</style>
|
||||
<style name="roundedCorners_30dp" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">30dp</item>
|
||||
</style>
|
||||
<style name="roundedCorners_33dp" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">33dp</item>
|
||||
</style>
|
||||
<style name="roundedCorners_40dp" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">40dp</item>
|
||||
|
||||
Reference in New Issue
Block a user