Added grid layout change option

This commit is contained in:
h4h13 2020-01-17 22:49:06 +05:30
parent fc7c3b30f5
commit 6210065221
49 changed files with 1571 additions and 1428 deletions

View file

@ -22,7 +22,7 @@ android {
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
applicationId "code.name.monkey.retromusic" applicationId "code.name.monkey.retromusic"
versionCode 403 versionCode 404
versionName '3.4.850' versionName '3.4.850'
multiDexEnabled true multiDexEnabled true
@ -175,6 +175,7 @@ dependencies {
implementation 'com.anjlab.android.iab.v3:library:1.1.0' implementation 'com.anjlab.android.iab.v3:library:1.1.0'
implementation 'com.r0adkll:slidableactivity:2.1.0' implementation 'com.r0adkll:slidableactivity:2.1.0'
implementation 'com.heinrichreimersoftware:material-intro:1.6' implementation 'com.heinrichreimersoftware:material-intro:1.6'
implementation 'me.zhanghai.android.fastscroll:library:1.1.0'
def dagger_version = "2.23.1" def dagger_version = "2.23.1"
implementation "com.google.dagger:dagger:$dagger_version" implementation "com.google.dagger:dagger:$dagger_version"

View file

@ -12,21 +12,15 @@
"profile_image": "https://i.imgur.com/Q5Nsx1R.jpg" "profile_image": "https://i.imgur.com/Q5Nsx1R.jpg"
}, },
{ {
"name": "Gaming Inc.", "name": "GameSpeck",
"summary": "Telegram group maintainer", "summary": "Telegram group maintainer",
"link": "https://www.gaminginc.tk/", "link": "https://t.me/GameSpeck",
"profile_image": "https://i.imgur.com/pfvN7d9.png" "profile_image": "https://imgur.com/B15Kb9a.jpg"
}, },
{ {
"name": "Milind Goel", "name": "Milind Goel",
"summary": "Github & Telegram maintainer", "summary": "Github & Telegram maintainer",
"link": "https://t.me/MilindGoel15", "link": "https://t.me/MilindGoel15",
"profile_image": "https://i.imgur.com/Bz4De21_d.jpg" "profile_image": "https://i.imgur.com/Bz4De21_d.jpg"
},
{
"name": "Abilas Sathiya",
"summary": "Design & Suggestions",
"link": "https://t.me/@abs2606",
"profile_image": "https://i.imgur.com/MUyEWlx.jpg"
} }
] ]

File diff suppressed because one or more lines are too long

View file

@ -187,14 +187,14 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
albumText.text = String.format( albumText.text = String.format(
"%s • %s", "%s • %s",
album.artistName, album.artistName,
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)) MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
) )
} else { } else {
albumText.text = String.format( albumText.text = String.format(
"%s • %s • %s", "%s • %s • %s",
album.artistName, album.artistName,
MusicUtil.getYearString(album.year), MusicUtil.getYearString(album.year),
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)) MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
) )
} }
loadAlbumCover() loadAlbumCover()

View file

@ -219,7 +219,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
text.text = String.format( text.text = String.format(
"%s • %s", "%s • %s",
MusicUtil.getArtistInfoString(this, artist), MusicUtil.getArtistInfoString(this, artist),
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs)) MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(artist.songs))
) )
songAdapter.swapDataSet(artist.songs) songAdapter.swapDataSet(artist.songs)

View file

@ -116,7 +116,7 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDet
private fun setupRecyclerView() { private fun setupRecyclerView() {
ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView) ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView)
songAdapter = ShuffleButtonSongAdapter(this, ArrayList(), R.layout.item_list, false, this) songAdapter = ShuffleButtonSongAdapter(this, ArrayList(), R.layout.item_list, this)
recyclerView.apply { recyclerView.apply {
itemAnimator = DefaultItemAnimator() itemAnimator = DefaultItemAnimator()
layoutManager = LinearLayoutManager(this@GenreDetailsActivity) layoutManager = LinearLayoutManager(this@GenreDetailsActivity)

View file

@ -77,7 +77,7 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.layoutManager = LinearLayoutManager(this)
if (playlist is AbsCustomPlaylist) { if (playlist is AbsCustomPlaylist) {
adapter = PlaylistSongAdapter(this, ArrayList(), R.layout.item_list, false, this) adapter = PlaylistSongAdapter(this, ArrayList(), R.layout.item_list, this)
recyclerView.adapter = adapter recyclerView.adapter = adapter
} else { } else {
recyclerViewDragDropManager = RecyclerViewDragDropManager() recyclerViewDragDropManager = RecyclerViewDragDropManager()
@ -85,7 +85,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
adapter = OrderablePlaylistSongAdapter(this, adapter = OrderablePlaylistSongAdapter(this,
ArrayList(), ArrayList(),
R.layout.item_list, R.layout.item_list,
false,
this, this,
object : OrderablePlaylistSongAdapter.OnMoveItemListener { object : OrderablePlaylistSongAdapter.OnMoveItemListener {
override fun onMoveItem(fromPosition: Int, toPosition: Int) { override fun onMoveItem(fromPosition: Int, toPosition: Int) {

View file

@ -22,22 +22,39 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.checkbox.MaterialCheckBox;
import java.util.List;
import code.name.monkey.appthemehelper.ThemeStore; import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.model.CategoryInfo; import code.name.monkey.retromusic.model.CategoryInfo;
import code.name.monkey.retromusic.util.SwipeAndDragHelper; import code.name.monkey.retromusic.util.SwipeAndDragHelper;
import com.google.android.material.checkbox.MaterialCheckBox;
import java.util.List;
public class CategoryInfoAdapter extends RecyclerView.Adapter<CategoryInfoAdapter.ViewHolder>
implements SwipeAndDragHelper.ActionCompletionContract {
static class ViewHolder extends RecyclerView.ViewHolder {
MaterialCheckBox checkBox;
View dragView;
TextView title;
ViewHolder(View view) {
super(view);
checkBox = view.findViewById(R.id.checkbox);
checkBox.setButtonTintList(
ColorStateList.valueOf(ThemeStore.Companion.accentColor(checkBox.getContext())));
title = view.findViewById(R.id.title);
dragView = view.findViewById(R.id.drag_view);
}
}
public class CategoryInfoAdapter extends RecyclerView.Adapter<CategoryInfoAdapter.ViewHolder> implements SwipeAndDragHelper.ActionCompletionContract {
private List<CategoryInfo> categoryInfos; private List<CategoryInfo> categoryInfos;
private ItemTouchHelper touchHelper; private ItemTouchHelper touchHelper;
public CategoryInfoAdapter(@NonNull List<CategoryInfo> categoryInfos) { public CategoryInfoAdapter(@NonNull List<CategoryInfo> categoryInfos) {
@ -46,52 +63,6 @@ public class CategoryInfoAdapter extends RecyclerView.Adapter<CategoryInfoAdapte
touchHelper = new ItemTouchHelper(swipeAndDragHelper); touchHelper = new ItemTouchHelper(swipeAndDragHelper);
} }
@Override
@NonNull
public CategoryInfoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.preference_dialog_library_categories_listitem, parent, false);
return new ViewHolder(view);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onBindViewHolder(@NonNull CategoryInfoAdapter.ViewHolder holder, int position) {
CategoryInfo categoryInfo = categoryInfos.get(position);
holder.checkBox.setChecked(categoryInfo.visible);
holder.title.setText(holder.title.getResources().getString(categoryInfo.category.stringRes));
holder.itemView.setOnClickListener(v -> {
if (!(categoryInfo.visible && isLastCheckedCategory(categoryInfo))) {
categoryInfo.visible = !categoryInfo.visible;
holder.checkBox.setChecked(categoryInfo.visible);
} else {
Toast.makeText(holder.itemView.getContext(), R.string.you_have_to_select_at_least_one_category, Toast.LENGTH_SHORT).show();
}
});
holder.dragView.setOnTouchListener((view, event) -> {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
touchHelper.startDrag(holder);
}
return false;
}
);
}
@Override
public int getItemCount() {
return categoryInfos.size();
}
@Override
public void onViewMoved(int oldPosition, int newPosition) {
CategoryInfo categoryInfo = categoryInfos.get(oldPosition);
categoryInfos.remove(oldPosition);
categoryInfos.add(newPosition, categoryInfo);
notifyItemMoved(oldPosition, newPosition);
}
public void attachToRecyclerView(RecyclerView recyclerView) { public void attachToRecyclerView(RecyclerView recyclerView) {
touchHelper.attachToRecyclerView(recyclerView); touchHelper.attachToRecyclerView(recyclerView);
} }
@ -106,26 +77,62 @@ public class CategoryInfoAdapter extends RecyclerView.Adapter<CategoryInfoAdapte
notifyDataSetChanged(); notifyDataSetChanged();
} }
@Override
public int getItemCount() {
return categoryInfos.size();
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onBindViewHolder(@NonNull CategoryInfoAdapter.ViewHolder holder, int position) {
CategoryInfo categoryInfo = categoryInfos.get(position);
holder.checkBox.setChecked(categoryInfo.visible);
holder.title.setText(holder.title.getResources().getString(categoryInfo.category.stringRes));
holder.itemView.setOnClickListener(v -> {
if (!(categoryInfo.visible && isLastCheckedCategory(categoryInfo))) {
categoryInfo.visible = !categoryInfo.visible;
holder.checkBox.setChecked(categoryInfo.visible);
} else {
Toast.makeText(holder.itemView.getContext(), R.string.you_have_to_select_at_least_one_category,
Toast.LENGTH_SHORT).show();
}
});
holder.dragView.setOnTouchListener((view, event) -> {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
touchHelper.startDrag(holder);
}
return false;
}
);
}
@Override
@NonNull
public CategoryInfoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.preference_dialog_library_categories_listitem, parent, false);
return new ViewHolder(view);
}
@Override
public void onViewMoved(int oldPosition, int newPosition) {
CategoryInfo categoryInfo = categoryInfos.get(oldPosition);
categoryInfos.remove(oldPosition);
categoryInfos.add(newPosition, categoryInfo);
notifyItemMoved(oldPosition, newPosition);
}
private boolean isLastCheckedCategory(CategoryInfo categoryInfo) { private boolean isLastCheckedCategory(CategoryInfo categoryInfo) {
if (categoryInfo.visible) { if (categoryInfo.visible) {
for (CategoryInfo c : categoryInfos) { for (CategoryInfo c : categoryInfos) {
if (c != categoryInfo && c.visible) return false; if (c != categoryInfo && c.visible) {
return false;
}
} }
} }
return true; return true;
} }
static class ViewHolder extends RecyclerView.ViewHolder {
MaterialCheckBox checkBox;
TextView title;
View dragView;
ViewHolder(View view) {
super(view);
checkBox = view.findViewById(R.id.checkbox);
checkBox.setButtonTintList(ColorStateList.valueOf(ThemeStore.Companion.accentColor(checkBox.getContext())));
title = view.findViewById(R.id.title);
dragView = view.findViewById(R.id.drag_view);
}
}
} }

View file

@ -1,7 +1,9 @@
package code.name.monkey.retromusic.adapter package code.name.monkey.retromusic.adapter
import android.app.Activity import android.app.Activity
import android.view.* import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
@ -11,64 +13,64 @@ import code.name.monkey.retromusic.views.CircularImageView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
class ContributorAdapter( class ContributorAdapter(
private var contributors: List<Contributor> private var contributors: List<Contributor>
) : RecyclerView.Adapter<ContributorAdapter.ViewHolder>() { ) : RecyclerView.Adapter<ContributorAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return if (viewType == HEADER) { return if (viewType == HEADER) {
ViewHolder( ViewHolder(
LayoutInflater.from(parent.context).inflate( LayoutInflater.from(parent.context).inflate(
R.layout.item_contributor_header, R.layout.item_contributor_header,
parent, parent,
false false
) )
) )
} else ViewHolder( } else ViewHolder(
LayoutInflater.from(parent.context).inflate( LayoutInflater.from(parent.context).inflate(
R.layout.item_contributor, R.layout.item_contributor,
parent, parent,
false false
) )
) )
} }
companion object { companion object {
const val HEADER: Int = 0 const val HEADER: Int = 0
const val ITEM: Int = 1 const val ITEM: Int = 1
} }
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
return if (position == 0) { return if (position == 0) {
HEADER HEADER
} else { } else {
ITEM ITEM
} }
} }
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val contributor = contributors[position] val contributor = contributors[position]
holder.bindData(contributor) holder.bindData(contributor)
holder.itemView.setOnClickListener { holder.itemView.setOnClickListener {
openUrl(it?.context as Activity, contributors[position].link) openUrl(it?.context as Activity, contributors[position].link)
} }
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return contributors.size return contributors.size
} }
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title: TextView = itemView.findViewById(R.id.title) val title: TextView = itemView.findViewById(R.id.title)
val text: TextView = itemView.findViewById(R.id.text) val text: TextView = itemView.findViewById(R.id.text)
val image: CircularImageView = itemView.findViewById(R.id.icon) val image: CircularImageView = itemView.findViewById(R.id.icon)
internal fun bindData(contributor: Contributor) { internal fun bindData(contributor: Contributor) {
title.text = contributor.name title.text = contributor.name
text.text = contributor.summary text.text = contributor.summary
println(contributor.profileImage) println(contributor.profileImage)
Glide.with(image.context).load(contributor.profileImage) Glide.with(image.context).load(contributor.profileImage)
.error(R.drawable.ic_account_white_24dp) .error(R.drawable.ic_account_white_24dp)
.placeholder(R.drawable.ic_account_white_24dp).dontAnimate().into(image) .placeholder(R.drawable.ic_account_white_24dp).dontAnimate().into(image)
} }
} }
} }

View file

@ -9,15 +9,19 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import java.util.* import java.util.ArrayList
import java.util.Locale
/** /**
* @author Hemanth S (h4h13). * @author Hemanth S (h4h13).
*/ */
class GenreAdapter( class GenreAdapter(
private val activity: Activity, dataSet: ArrayList<Genre>, private val mItemLayoutRes: Int private val activity: Activity,
dataSet: ArrayList<Genre>,
private val mItemLayoutRes: Int
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() { ) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
var dataSet = ArrayList<Genre>() var dataSet = ArrayList<Genre>()
private set private set
@ -32,7 +36,12 @@ class GenreAdapter(
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val genre = dataSet[position] val genre = dataSet[position]
holder.title?.text = genre.name holder.title?.text = genre.name
holder.text?.text = String.format(Locale.getDefault(), "%d %s", genre.songCount, if (genre.songCount > 1) activity.getString(R.string.songs) else activity.getString(R.string.song)) holder.text?.text = String.format(
Locale.getDefault(),
"%d %s",
genre.songCount,
if (genre.songCount > 1) activity.getString(R.string.songs) else activity.getString(R.string.song)
)
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {

View file

@ -23,7 +23,8 @@ import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
class HomeAdapter( class HomeAdapter(
private val activity: AppCompatActivity, private val displayMetrics: DisplayMetrics private val activity: AppCompatActivity,
private val displayMetrics: DisplayMetrics
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var list = ArrayList<Home>() private var list = ArrayList<Home>()
@ -137,14 +138,9 @@ class HomeAdapter(
if (songs.isNotEmpty()) { if (songs.isNotEmpty()) {
recyclerView.apply { recyclerView.apply {
show() show()
val songAdapter = SongAdapter( val songAdapter = SongAdapter(activity, songs, R.layout.item_album_card, null)
activity, songs, R.layout.item_album_card, false, null layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
)
layoutManager = GridLayoutManager(
activity, 1, GridLayoutManager.HORIZONTAL, false
)
adapter = songAdapter adapter = songAdapter
} }
title.text = activity.getString(titleRes) title.text = activity.getString(titleRes)
} }

View file

@ -23,7 +23,8 @@ import com.bumptech.glide.Glide
import android.util.Pair as UtilPair import android.util.Pair as UtilPair
class SearchAdapter( class SearchAdapter(
private val activity: AppCompatActivity, private var dataSet: List<Any>? private val activity: AppCompatActivity,
private var dataSet: List<Any>?
) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() { ) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() {
fun swapDataSet(dataSet: MutableList<Any>) { fun swapDataSet(dataSet: MutableList<Any>) {
@ -39,7 +40,13 @@ class SearchAdapter(
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return if (viewType == HEADER) ViewHolder(LayoutInflater.from(activity).inflate(R.layout.sub_header, parent, false), viewType) return if (viewType == HEADER) ViewHolder(
LayoutInflater.from(activity).inflate(
R.layout.sub_header,
parent,
false
), viewType
)
else else
ViewHolder(LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false), viewType) ViewHolder(LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false), viewType)
} }
@ -51,14 +58,14 @@ class SearchAdapter(
holder.title?.text = album.title holder.title?.text = album.title
holder.text?.text = album.artistName holder.text?.text = album.artistName
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity).build().into(holder.image) .checkIgnoreMediaStore(activity).build().into(holder.image)
} }
ARTIST -> { ARTIST -> {
val artist = dataSet?.get(position) as Artist val artist = dataSet?.get(position) as Artist
holder.title?.text = artist.name holder.title?.text = artist.name
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist) holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
ArtistGlideRequest.Builder.from(Glide.with(activity), artist).build() ArtistGlideRequest.Builder.from(Glide.with(activity), artist).build()
.into(holder.image) .into(holder.image)
} }
SONG -> { SONG -> {
val song = dataSet?.get(position) as Song val song = dataSet?.get(position) as Song
@ -108,11 +115,17 @@ class SearchAdapter(
val item = dataSet!![adapterPosition] val item = dataSet!![adapterPosition]
when (itemViewType) { when (itemViewType) {
ALBUM -> { ALBUM -> {
val options = ActivityOptions.makeSceneTransitionAnimation(activity, UtilPair.create(image, activity.getString(R.string.transition_album_art))) val options = ActivityOptions.makeSceneTransitionAnimation(
activity,
UtilPair.create(image, activity.getString(R.string.transition_album_art))
)
NavigationUtil.goToAlbumOptions(activity, (item as Album).id, options) NavigationUtil.goToAlbumOptions(activity, (item as Album).id, options)
} }
ARTIST -> { ARTIST -> {
val options = ActivityOptions.makeSceneTransitionAnimation(activity, UtilPair.create(image, activity.getString(R.string.transition_artist_image))) val options = ActivityOptions.makeSceneTransitionAnimation(
activity,
UtilPair.create(image, activity.getString(R.string.transition_artist_image))
)
NavigationUtil.goToArtistOptions(activity, (item as Artist).id, options) NavigationUtil.goToArtistOptions(activity, (item as Artist).id, options)
} }
GENRE -> { GENRE -> {

View file

@ -12,37 +12,38 @@ import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.signature.MediaStoreSignature import com.bumptech.glide.signature.MediaStoreSignature
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import me.zhanghai.android.fastscroll.PopupTextProvider
import java.io.File import java.io.File
import java.text.DecimalFormat import java.text.DecimalFormat
import java.util.* import java.util.ArrayList
import kotlin.math.log10 import kotlin.math.log10
import kotlin.math.pow import kotlin.math.pow
class SongFileAdapter( class SongFileAdapter(
private val activity: AppCompatActivity, private val activity: AppCompatActivity,
private var dataSet: List<File>?, private var dataSet: List<File>,
private val itemLayoutRes: Int, private val itemLayoutRes: Int,
private val callbacks: Callbacks?, private val callbacks: Callbacks?,
cabHolder: CabHolder? cabHolder: CabHolder?
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>( ) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(
activity, cabHolder, R.menu.menu_media_selection activity, cabHolder, R.menu.menu_media_selection
), FastScrollRecyclerView.SectionedAdapter { ), PopupTextProvider {
init { init {
this.setHasStableIds(true) this.setHasStableIds(true)
} }
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
return if (dataSet!![position].isDirectory) FOLDER else FILE return if (dataSet[position].isDirectory) FOLDER else FILE
} }
override fun getItemId(position: Int): Long { override fun getItemId(position: Int): Long {
return dataSet!![position].hashCode().toLong() return dataSet[position].hashCode().toLong()
} }
fun swapDataSet(songFiles: List<File>) { fun swapDataSet(songFiles: List<File>) {
@ -55,7 +56,7 @@ class SongFileAdapter(
} }
override fun onBindViewHolder(holder: ViewHolder, index: Int) { override fun onBindViewHolder(holder: ViewHolder, index: Int) {
val file = dataSet!![index] val file = dataSet[index]
holder.itemView.isActivated = isChecked(file) holder.itemView.isActivated = isChecked(file)
holder.title?.text = getFileTitle(file) holder.title?.text = getFileTitle(file)
if (holder.text != null) { if (holder.text != null) {
@ -87,24 +88,23 @@ class SongFileAdapter(
it.setImageResource(R.drawable.ic_folder_white_24dp) it.setImageResource(R.drawable.ic_folder_white_24dp)
} }
holder.imageTextContainer?.setCardBackgroundColor(ATHUtil.resolveColor(activity, R.attr.colorSurface)) holder.imageTextContainer?.setCardBackgroundColor(ATHUtil.resolveColor(activity, R.attr.colorSurface))
} else { } else {
val error = RetroUtil.getTintedVectorDrawable( val error = RetroUtil.getTintedVectorDrawable(
activity, R.drawable.ic_file_music_white_24dp, iconColor activity, R.drawable.ic_file_music_white_24dp, iconColor
) )
Glide.with(activity).load(AudioFileCover(file.path)) Glide.with(activity).load(AudioFileCover(file.path))
.diskCacheStrategy(DiskCacheStrategy.NONE).error(error).placeholder(error) .diskCacheStrategy(DiskCacheStrategy.NONE).error(error).placeholder(error)
.animate(android.R.anim.fade_in) .animate(android.R.anim.fade_in)
.signature(MediaStoreSignature("", file.lastModified(), 0)).into(holder.image) .signature(MediaStoreSignature("", file.lastModified(), 0)).into(holder.image)
} }
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return dataSet!!.size return dataSet.size
} }
override fun getIdentifier(position: Int): File? { override fun getIdentifier(position: Int): File? {
return dataSet!![position] return dataSet[position]
} }
override fun getName(`object`: File): String { override fun getName(`object`: File): String {
@ -116,8 +116,12 @@ class SongFileAdapter(
callbacks.onMultipleItemAction(menuItem, selection) callbacks.onMultipleItemAction(menuItem, selection)
} }
override fun getSectionName(position: Int): String { override fun getPopupText(position: Int): String {
return dataSet!![position].name[0].toString().toUpperCase() return getSectionName(position)
}
private fun getSectionName(position: Int): String {
return MusicUtil.getSectionName(dataSet[position].name)
} }
interface Callbacks { interface Callbacks {
@ -135,7 +139,7 @@ class SongFileAdapter(
menu?.setOnClickListener { v -> menu?.setOnClickListener { v ->
val position = adapterPosition val position = adapterPosition
if (isPositionInRange(position)) { if (isPositionInRange(position)) {
callbacks.onFileMenuClicked(dataSet!![position], v) callbacks.onFileMenuClicked(dataSet[position], v)
} }
} }
} }
@ -150,7 +154,7 @@ class SongFileAdapter(
if (isInQuickSelectMode) { if (isInQuickSelectMode) {
toggleChecked(position) toggleChecked(position)
} else { } else {
callbacks?.onFileSelected(dataSet!![position]) callbacks?.onFileSelected(dataSet[position])
} }
} }
} }
@ -161,7 +165,7 @@ class SongFileAdapter(
} }
private fun isPositionInRange(position: Int): Boolean { private fun isPositionInRange(position: Int): Boolean {
return position >= 0 && position < dataSet!!.size return position >= 0 && position < dataSet.size
} }
} }

View file

@ -25,7 +25,7 @@ import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import me.zhanghai.android.fastscroll.PopupTextProvider
open class AlbumAdapter( open class AlbumAdapter(
protected val activity: AppCompatActivity, protected val activity: AppCompatActivity,
@ -37,7 +37,7 @@ open class AlbumAdapter(
activity, activity,
cabHolder, cabHolder,
R.menu.menu_media_selection R.menu.menu_media_selection
), FastScrollRecyclerView.SectionedAdapter { ), PopupTextProvider {
var dataSet: ArrayList<Album> var dataSet: ArrayList<Album>
protected set protected set
@ -168,7 +168,11 @@ open class AlbumAdapter(
return songs return songs
} }
override fun getSectionName(position: Int): String { override fun getPopupText(position: Int): String {
return getSectionName(position)
}
private fun getSectionName(position: Int): String {
var sectionName: String? = null var sectionName: String? = null
when (PreferenceUtil.getInstance(activity).albumSortOrder) { when (PreferenceUtil.getInstance(activity).albumSortOrder) {
SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName = SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName =

View file

@ -70,7 +70,7 @@ class AlbumCoverPagerAdapter(
private val layout: Int private val layout: Int
get() { get() {
return when (PreferenceUtil.getInstance(activity).albumCoverStyle) { return when (PreferenceUtil.getInstance(requireContext()).albumCoverStyle) {
AlbumCoverStyle.NORMAL -> R.layout.fragment_album_cover AlbumCoverStyle.NORMAL -> R.layout.fragment_album_cover
AlbumCoverStyle.FLAT -> R.layout.fragment_album_flat_cover AlbumCoverStyle.FLAT -> R.layout.fragment_album_flat_cover
AlbumCoverStyle.CIRCLE -> R.layout.fragment_album_circle_cover AlbumCoverStyle.CIRCLE -> R.layout.fragment_album_circle_cover
@ -95,7 +95,7 @@ class AlbumCoverPagerAdapter(
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
val finalLayout = when { val finalLayout = when {
PreferenceUtil.getInstance(activity).carouselEffect() -> R.layout.fragment_album_carousel_cover PreferenceUtil.getInstance(requireContext()).carouselEffect() -> R.layout.fragment_album_carousel_cover
else -> layout else -> layout
} }
val view = inflater.inflate(finalLayout, container, false) val view = inflater.inflate(finalLayout, container, false)

View file

@ -13,59 +13,59 @@ import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import java.util.* import java.util.ArrayList
class HorizontalAlbumAdapter( class HorizontalAlbumAdapter(
activity: AppCompatActivity, activity: AppCompatActivity,
dataSet: ArrayList<Album>, dataSet: ArrayList<Album>,
usePalette: Boolean, usePalette: Boolean,
cabHolder: CabHolder? cabHolder: CabHolder?
) : AlbumAdapter( ) : AlbumAdapter(
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, usePalette, cabHolder activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, usePalette, cabHolder
) { ) {
override fun createViewHolder(view: View, viewType: Int): ViewHolder { override fun createViewHolder(view: View, viewType: Int): ViewHolder {
val params = view.layoutParams as ViewGroup.MarginLayoutParams val params = view.layoutParams as ViewGroup.MarginLayoutParams
HorizontalAdapterHelper.applyMarginToLayoutParams(activity, params, viewType) HorizontalAdapterHelper.applyMarginToLayoutParams(activity, params, viewType)
return ViewHolder(view) return ViewHolder(view)
} }
override fun setColors(color: Int, holder: ViewHolder) { override fun setColors(color: Int, holder: ViewHolder) {
holder.title?.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color))) holder.title?.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
holder.text?.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color))) holder.text?.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
} }
override fun loadAlbumCover(album: Album, holder: ViewHolder) { override fun loadAlbumCover(album: Album, holder: ViewHolder) {
if (holder.image == null) return if (holder.image == null) return
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity).generatePalette(activity).build() .checkIgnoreMediaStore(activity).generatePalette(activity).build()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onLoadCleared(placeholder: Drawable?) { override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder) super.onLoadCleared(placeholder)
setColors(albumArtistFooterColor, holder) setColors(albumArtistFooterColor, holder)
} }
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
if (usePalette) setColors(color, holder) if (usePalette) setColors(color, holder)
else setColors(albumArtistFooterColor, holder) else setColors(albumArtistFooterColor, holder)
} }
}) })
} }
override fun getAlbumText(album: Album): String? { override fun getAlbumText(album: Album): String? {
return MusicUtil.getYearString(album.year) return MusicUtil.getYearString(album.year)
} }
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
return HorizontalAdapterHelper.getItemViewtype(position, itemCount) return HorizontalAdapterHelper.getItemViewtype(position, itemCount)
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return dataSet.size return dataSet.size
} }
companion object { companion object {
val TAG: String = AlbumAdapter::class.java.simpleName val TAG: String = AlbumAdapter::class.java.simpleName
} }
} }

View file

@ -23,7 +23,7 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import me.zhanghai.android.fastscroll.PopupTextProvider
import java.util.ArrayList import java.util.ArrayList
class ArtistAdapter( class ArtistAdapter(
@ -34,7 +34,7 @@ class ArtistAdapter(
cabHolder: CabHolder? cabHolder: CabHolder?
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>( ) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(
activity, cabHolder, R.menu.menu_media_selection activity, cabHolder, R.menu.menu_media_selection
), FastScrollRecyclerView.SectionedAdapter { ), PopupTextProvider {
fun swapDataSet(dataSet: ArrayList<Artist>) { fun swapDataSet(dataSet: ArrayList<Artist>) {
this.dataSet = dataSet this.dataSet = dataSet
@ -70,7 +70,7 @@ class ArtistAdapter(
fun setColors(color: Int, holder: ViewHolder) { fun setColors(color: Int, holder: ViewHolder) {
if (holder.paletteColorContainer != null) { if (holder.paletteColorContainer != null) {
holder.paletteColorContainer?.backgroundTintList = ColorStateList.valueOf(color) holder.paletteColorContainer?.setBackgroundColor(color)
holder.title?.setTextColor( holder.title?.setTextColor(
MaterialValueHelper.getPrimaryTextColor( MaterialValueHelper.getPrimaryTextColor(
activity, ColorUtil.isColorLight( activity, ColorUtil.isColorLight(
@ -126,7 +126,11 @@ class ArtistAdapter(
return songs return songs
} }
override fun getSectionName(position: Int): String { override fun getPopupText(position: Int): String {
return getSectionName(position)
}
private fun getSectionName(position: Int): String {
return MusicUtil.getSectionName(dataSet[position].name) return MusicUtil.getSectionName(dataSet[position].name)
} }

View file

@ -3,26 +3,28 @@ package code.name.monkey.retromusic.adapter.base;
import android.content.Context; import android.content.Context;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import androidx.annotation.MenuRes; import androidx.annotation.MenuRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.afollestad.materialcab.MaterialCab;
import java.util.ArrayList;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.interfaces.CabHolder; import code.name.monkey.retromusic.interfaces.CabHolder;
import com.afollestad.materialcab.MaterialCab;
import java.util.ArrayList;
public abstract class AbsMultiSelectAdapter<VH extends RecyclerView.ViewHolder, I> extends RecyclerView.Adapter<VH> implements MaterialCab.Callback { public abstract class AbsMultiSelectAdapter<VH extends RecyclerView.ViewHolder, I> extends RecyclerView.Adapter<VH>
implements MaterialCab.Callback {
private MaterialCab cab;
@Nullable @Nullable
private final CabHolder cabHolder; private final CabHolder cabHolder;
private final Context context;
private MaterialCab cab;
private ArrayList<I> checked; private ArrayList<I> checked;
private final Context context;
private int menuRes; private int menuRes;
public AbsMultiSelectAdapter(@NonNull Context context, @Nullable CabHolder cabHolder, @MenuRes int menuRes) { public AbsMultiSelectAdapter(@NonNull Context context, @Nullable CabHolder cabHolder, @MenuRes int menuRes) {
@ -32,22 +34,27 @@ public abstract class AbsMultiSelectAdapter<VH extends RecyclerView.ViewHolder,
this.context = context; this.context = context;
} }
protected void setMultiSelectMenuRes(@MenuRes int menuRes) { @Override
this.menuRes = menuRes; public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
return true;
} }
protected boolean toggleChecked(final int position) { @Override
if (cabHolder != null) { public boolean onCabFinished(MaterialCab materialCab) {
I identifier = getIdentifier(position); clearChecked();
if (identifier == null) return false; return true;
}
if (!checked.remove(identifier)) checked.add(identifier); @Override
public boolean onCabItemClicked(MenuItem menuItem) {
notifyItemChanged(position); if (menuItem.getItemId() == R.id.action_multi_select_adapter_check_all) {
updateCab(); checkAll();
return true; } else {
onMultipleItemAction(menuItem, new ArrayList<>(checked));
cab.finish();
clearChecked();
} }
return false; return true;
} }
protected void checkAll() { protected void checkAll() {
@ -64,21 +71,11 @@ public abstract class AbsMultiSelectAdapter<VH extends RecyclerView.ViewHolder,
} }
} }
private void updateCab() { @Nullable
if (cabHolder != null) { protected abstract I getIdentifier(int position);
if (cab == null || !cab.isActive()) {
cab = cabHolder.openCab(menuRes, this);
}
final int size = checked.size();
if (size <= 0) cab.finish();
else if (size == 1) cab.setTitle(getName(checked.get(0)));
else cab.setTitle(context.getString(R.string.x_selected, size));
}
}
private void clearChecked() { protected String getName(I object) {
checked.clear(); return object.toString();
notifyDataSetChanged();
} }
protected boolean isChecked(I identifier) { protected boolean isChecked(I identifier) {
@ -89,35 +86,48 @@ public abstract class AbsMultiSelectAdapter<VH extends RecyclerView.ViewHolder,
return cab != null && cab.isActive(); return cab != null && cab.isActive();
} }
@Override
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
return true;
}
@Override
public boolean onCabItemClicked(MenuItem menuItem) {
if (menuItem.getItemId() == R.id.action_multi_select_adapter_check_all) {
checkAll();
} else {
onMultipleItemAction(menuItem, new ArrayList<>(checked));
cab.finish();
clearChecked();
}
return true;
}
@Override
public boolean onCabFinished(MaterialCab materialCab) {
clearChecked();
return true;
}
protected String getName(I object) {
return object.toString();
}
@Nullable
protected abstract I getIdentifier(int position);
protected abstract void onMultipleItemAction(MenuItem menuItem, ArrayList<I> selection); protected abstract void onMultipleItemAction(MenuItem menuItem, ArrayList<I> selection);
protected void setMultiSelectMenuRes(@MenuRes int menuRes) {
this.menuRes = menuRes;
}
protected boolean toggleChecked(final int position) {
if (cabHolder != null) {
I identifier = getIdentifier(position);
if (identifier == null) {
return false;
}
if (!checked.remove(identifier)) {
checked.add(identifier);
}
notifyItemChanged(position);
updateCab();
return true;
}
return false;
}
private void clearChecked() {
checked.clear();
notifyDataSetChanged();
}
private void updateCab() {
if (cabHolder != null) {
if (cab == null || !cab.isActive()) {
cab = cabHolder.openCab(menuRes, this);
}
final int size = checked.size();
if (size <= 0) {
cab.finish();
} else if (size == 1) {
cab.setTitle(getName(checked.get(0)));
} else {
cab.setTitle(context.getString(R.string.x_selected, size));
}
}
}
} }

View file

@ -14,6 +14,7 @@
package code.name.monkey.retromusic.adapter.base; package code.name.monkey.retromusic.adapter.base;
import android.graphics.Color;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
@ -22,7 +23,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import code.name.monkey.appthemehelper.util.ATHUtil;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import com.google.android.material.card.MaterialCardView; import com.google.android.material.card.MaterialCardView;
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder; import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder;
@ -97,8 +97,7 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
dummyContainer = itemView.findViewById(R.id.dummy_view); dummyContainer = itemView.findViewById(R.id.dummy_view);
if (imageContainerCard != null) { if (imageContainerCard != null) {
imageContainerCard.setCardBackgroundColor( imageContainerCard.setCardBackgroundColor(Color.TRANSPARENT);
ATHUtil.INSTANCE.resolveColor(itemView.getContext(), R.attr.colorSurface));
} }
itemView.setOnClickListener(this); itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this); itemView.setOnLongClickListener(this);

View file

@ -1,5 +1,6 @@
package code.name.monkey.retromusic.adapter.playlist package code.name.monkey.retromusic.adapter.playlist
import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
@ -15,6 +16,8 @@ import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.dialogs.ClearSmartPlaylistDialog import code.name.monkey.retromusic.dialogs.ClearSmartPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
@ -26,17 +29,17 @@ import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import java.util.* import java.util.ArrayList
class PlaylistAdapter( class PlaylistAdapter(
private val activity: AppCompatActivity, private val activity: AppCompatActivity,
var dataSet: ArrayList<Playlist>, var dataSet: ArrayList<Playlist>,
private var itemLayoutRes: Int, private var itemLayoutRes: Int,
cabHolder: CabHolder? cabHolder: CabHolder?
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>( ) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(
activity, activity,
cabHolder, cabHolder,
R.menu.menu_playlists_selection R.menu.menu_playlists_selection
) { ) {
var songs = ArrayList<Song>() var songs = ArrayList<Song>()
@ -77,12 +80,26 @@ class PlaylistAdapter(
holder.title?.text = getPlaylistTitle(playlist) holder.title?.text = getPlaylistTitle(playlist)
holder.text?.text = getPlaylistText(playlist) holder.text?.text = getPlaylistText(playlist)
holder.image?.setImageDrawable(getIconRes(playlist)) holder.image?.setImageDrawable(getIconRes(playlist))
val isChecked = isChecked(playlist)
if (isChecked) {
holder.menu?.hide()
} else {
holder.menu?.show()
}
} }
private fun getIconRes(playlist: Playlist): Drawable { private fun getIconRes(playlist: Playlist): Drawable {
return if (MusicUtil.isFavoritePlaylist(activity, playlist)) return if (MusicUtil.isFavoritePlaylist(activity, playlist))
TintHelper.createTintedDrawable(activity, R.drawable.ic_favorite_white_24dp, ThemeStore.accentColor(activity))!! TintHelper.createTintedDrawable(
else TintHelper.createTintedDrawable(activity, R.drawable.ic_playlist_play_white_24dp, ATHUtil.resolveColor(activity, R.attr.colorControlNormal))!! activity,
R.drawable.ic_favorite_white_24dp,
ThemeStore.accentColor(activity)
)
else TintHelper.createTintedDrawable(
activity,
R.drawable.ic_playlist_play_white_24dp,
ATHUtil.resolveColor(activity, R.attr.colorControlNormal)
)
} }
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
@ -109,7 +126,7 @@ class PlaylistAdapter(
val playlist = selection[i] val playlist = selection[i]
if (playlist is AbsSmartPlaylist) { if (playlist is AbsSmartPlaylist) {
ClearSmartPlaylistDialog.create(playlist).show( ClearSmartPlaylistDialog.create(playlist).show(
activity.supportFragmentManager, "CLEAR_PLAYLIST_" + playlist.name activity.supportFragmentManager, "CLEAR_PLAYLIST_" + playlist.name
) )
selection.remove(playlist) selection.remove(playlist)
i-- i--
@ -118,13 +135,13 @@ class PlaylistAdapter(
} }
if (selection.size > 0) { if (selection.size > 0) {
DeletePlaylistDialog.create(selection) DeletePlaylistDialog.create(selection)
.show(activity.supportFragmentManager, "DELETE_PLAYLIST") .show(activity.supportFragmentManager, "DELETE_PLAYLIST")
} }
} }
else -> SongsMenuHelper.handleMenuClick( else -> SongsMenuHelper.handleMenuClick(
activity, activity,
getSongList(selection), getSongList(selection),
menuItem.itemId menuItem.itemId
) )
} }
} }
@ -157,15 +174,14 @@ class PlaylistAdapter(
image?.apply { image?.apply {
val iconPadding = activity.resources.getDimensionPixelSize(R.dimen.list_item_image_icon_padding) val iconPadding = activity.resources.getDimensionPixelSize(R.dimen.list_item_image_icon_padding)
setPadding(iconPadding, iconPadding, iconPadding, iconPadding) setPadding(iconPadding, iconPadding, iconPadding, iconPadding)
//setColorFilter(ATHUtil.resolveColor(activity, R.attr.iconColor), PorterDuff.Mode.SRC_IN)
} }
menu?.setOnClickListener { view -> menu?.setOnClickListener { view ->
val playlist = dataSet[adapterPosition] val playlist = dataSet[adapterPosition]
val popupMenu = PopupMenu(activity, view) val popupMenu = PopupMenu(activity, view)
popupMenu.inflate( popupMenu.inflate(
if (itemViewType == SMART_PLAYLIST) R.menu.menu_item_smart_playlist if (itemViewType == SMART_PLAYLIST) R.menu.menu_item_smart_playlist
else R.menu.menu_item_playlist else R.menu.menu_item_playlist
) )
if (playlist is LastAddedPlaylist) { if (playlist is LastAddedPlaylist) {
popupMenu.menu.findItem(R.id.action_clear_playlist).isVisible = false popupMenu.menu.findItem(R.id.action_clear_playlist).isVisible = false
@ -174,14 +190,14 @@ class PlaylistAdapter(
if (item.itemId == R.id.action_clear_playlist) { if (item.itemId == R.id.action_clear_playlist) {
if (playlist is AbsSmartPlaylist) { if (playlist is AbsSmartPlaylist) {
ClearSmartPlaylistDialog.create(playlist).show( ClearSmartPlaylistDialog.create(playlist).show(
activity.supportFragmentManager, activity.supportFragmentManager,
"CLEAR_SMART_PLAYLIST_" + playlist.name "CLEAR_SMART_PLAYLIST_" + playlist.name
) )
return@setOnMenuItemClickListener true return@setOnMenuItemClickListener true
} }
} }
PlaylistMenuHelper.handleMenuClick( PlaylistMenuHelper.handleMenuClick(
activity, dataSet[adapterPosition], item activity, dataSet[adapterPosition], item
) )
} }
popupMenu.show() popupMenu.show()
@ -189,7 +205,7 @@ class PlaylistAdapter(
imageTextContainer?.apply { imageTextContainer?.apply {
cardElevation = 0f cardElevation = 0f
setCardBackgroundColor(ATHUtil.resolveColor(activity, R.attr.colorSurface)) setCardBackgroundColor(Color.TRANSPARENT)
} }
} }

View file

@ -1,95 +1,80 @@
package code.name.monkey.retromusic.adapter.song package code.name.monkey.retromusic.adapter.song
import android.view.* import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import java.util.* import java.util.ArrayList
abstract class AbsOffsetSongAdapter : SongAdapter { abstract class AbsOffsetSongAdapter(
activity: AppCompatActivity,
dataSet: ArrayList<Song>,
@LayoutRes itemLayoutRes: Int,
cabHolder: CabHolder?
) : SongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
constructor( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongAdapter.ViewHolder {
activity: AppCompatActivity, if (viewType == OFFSET_ITEM) {
dataSet: ArrayList<Song>, @LayoutRes itemLayoutRes: Int, val view = LayoutInflater.from(activity)
usePalette: Boolean, .inflate(R.layout.item_list_quick_actions, parent, false)
cabHolder: CabHolder? return createViewHolder(view)
) : super(activity, dataSet, itemLayoutRes, usePalette, cabHolder) }
return super.onCreateViewHolder(parent, viewType)
}
constructor( override fun createViewHolder(view: View): SongAdapter.ViewHolder {
activity: AppCompatActivity, return ViewHolder(view)
dataSet: ArrayList<Song>, @LayoutRes itemLayoutRes: Int, }
usePalette: Boolean,
cabHolder: CabHolder?,
showSectionName: Boolean
) : super(activity, dataSet, itemLayoutRes, usePalette, cabHolder, showSectionName) {
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongAdapter.ViewHolder { override fun getItemId(position: Int): Long {
if (viewType == OFFSET_ITEM) { var positionFinal = position
val view = LayoutInflater.from(activity) positionFinal--
.inflate(R.layout.item_list_quick_actions, parent, false) return if (positionFinal < 0) -2 else super.getItemId(positionFinal)
return createViewHolder(view) }
}
return super.onCreateViewHolder(parent, viewType)
}
override fun createViewHolder(view: View): SongAdapter.ViewHolder { override fun getIdentifier(position: Int): Song? {
return ViewHolder(view) var positionFinal = position
} positionFinal--
return if (positionFinal < 0) null else super.getIdentifier(positionFinal)
}
override fun getItemId(position: Int): Long { override fun getItemCount(): Int {
var positionFinal = position val superItemCount = super.getItemCount()
positionFinal-- return if (superItemCount == 0) 0 else superItemCount + 1
return if (positionFinal < 0) -2 else super.getItemId(positionFinal) }
}
override fun getIdentifier(position: Int): Song? { override fun getItemViewType(position: Int): Int {
var positionFinal = position return if (position == 0) OFFSET_ITEM else SONG
positionFinal-- }
return if (positionFinal < 0) null else super.getIdentifier(positionFinal)
}
override fun getItemCount(): Int { open inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
val superItemCount = super.getItemCount()
return if (superItemCount == 0) 0 else superItemCount + 1
}
override fun getItemViewType(position: Int): Int { override // could also return null, just to be safe return empty song
return if (position == 0) OFFSET_ITEM else SONG val song: Song
} get() = if (itemViewType == OFFSET_ITEM) Song.emptySong else dataSet[adapterPosition - 1]
override fun getSectionName(position: Int): String { override fun onClick(v: View?) {
var positionF = position if (isInQuickSelectMode && itemViewType != OFFSET_ITEM) {
positionF-- toggleChecked(adapterPosition)
return if (positionF < 0) "" else super.getSectionName(positionF) } else {
} MusicPlayerRemote.openQueue(dataSet, adapterPosition - 1, true)
}
}
open inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) { override fun onLongClick(v: View?): Boolean {
if (itemViewType == OFFSET_ITEM) return false
toggleChecked(adapterPosition)
return true
}
}
override // could also return null, just to be safe return empty song companion object {
val song: Song const val OFFSET_ITEM = 0
get() = if (itemViewType == OFFSET_ITEM) Song.emptySong else dataSet[adapterPosition - 1] const val SONG = 1
}
override fun onClick(v: View?) {
if (isInQuickSelectMode && itemViewType != OFFSET_ITEM) {
toggleChecked(adapterPosition)
} else {
MusicPlayerRemote.openQueue(dataSet, adapterPosition - 1, true)
}
}
override fun onLongClick(v: View?): Boolean {
if (itemViewType == OFFSET_ITEM) return false
toggleChecked(adapterPosition)
return true
}
}
companion object {
const val OFFSET_ITEM = 0
const val SONG = 1
}
} }

View file

@ -1,134 +1,138 @@
package code.name.monkey.retromusic.adapter.song package code.name.monkey.retromusic.adapter.song
import android.view.* import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.R.menu
import code.name.monkey.retromusic.dialogs.RemoveFromPlaylistDialog import code.name.monkey.retromusic.dialogs.RemoveFromPlaylistDialog
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.* import code.name.monkey.retromusic.model.PlaylistSong
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import com.h6ah4i.android.widget.advrecyclerview.draggable.* import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemViewHolder
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
class OrderablePlaylistSongAdapter( class OrderablePlaylistSongAdapter(
activity: AppCompatActivity, activity: AppCompatActivity,
dataSet: ArrayList<Song>, dataSet: ArrayList<Song>,
itemLayoutRes: Int, itemLayoutRes: Int,
usePalette: Boolean, cabHolder: CabHolder?,
cabHolder: CabHolder?, private val onMoveItemListener: OnMoveItemListener?
private val onMoveItemListener: OnMoveItemListener?
) : PlaylistSongAdapter( ) : PlaylistSongAdapter(
activity, dataSet, itemLayoutRes, usePalette, cabHolder activity, dataSet, itemLayoutRes, cabHolder
), DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> { ), DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
init { init {
setMultiSelectMenuRes(code.name.monkey.retromusic.R.menu.menu_playlists_songs_selection) setMultiSelectMenuRes(menu.menu_playlists_songs_selection)
} }
override fun createViewHolder(view: View): SongAdapter.ViewHolder { override fun createViewHolder(view: View): SongAdapter.ViewHolder {
return ViewHolder(view) return ViewHolder(view)
} }
override fun getItemId(position: Int): Long { override fun getItemId(position: Int): Long {
var positionFinal = position var positionFinal = position
positionFinal-- positionFinal--
var long: Long = 0 var long: Long = 0
if (positionFinal < 0) { if (positionFinal < 0) {
long = -2 long = -2
} else { } else {
if (dataSet[positionFinal] is PlaylistSong) { if (dataSet[positionFinal] is PlaylistSong) {
long = (dataSet[positionFinal] as PlaylistSong).idInPlayList.toLong() long = (dataSet[positionFinal] as PlaylistSong).idInPlayList.toLong()
} }
} }
return long return long
} }
override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<Song>) { override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<Song>) {
when (menuItem.itemId) { when (menuItem.itemId) {
R.id.action_remove_from_playlist -> { R.id.action_remove_from_playlist -> {
RemoveFromPlaylistDialog.create(selection as ArrayList<PlaylistSong>) RemoveFromPlaylistDialog.create(selection as ArrayList<PlaylistSong>)
.show(activity.supportFragmentManager, "ADD_PLAYLIST") .show(activity.supportFragmentManager, "ADD_PLAYLIST")
return return
} }
} }
super.onMultipleItemAction(menuItem, selection) super.onMultipleItemAction(menuItem, selection)
} }
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean { override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
return onMoveItemListener != null && position > 0 && (ViewUtil.hitTest( return onMoveItemListener != null && position > 0 && (ViewUtil.hitTest(
holder.dragView!!, x, y holder.dragView!!, x, y
) || ViewUtil.hitTest(holder.image!!, x, y)) ) || ViewUtil.hitTest(holder.image!!, x, y))
} }
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange { override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange {
return ItemDraggableRange(1, dataSet.size) return ItemDraggableRange(1, dataSet.size)
} }
override fun onMoveItem(fromPosition: Int, toPosition: Int) { override fun onMoveItem(fromPosition: Int, toPosition: Int) {
if (onMoveItemListener != null && fromPosition != toPosition) { if (onMoveItemListener != null && fromPosition != toPosition) {
onMoveItemListener.onMoveItem(fromPosition - 1, toPosition - 1) onMoveItemListener.onMoveItem(fromPosition - 1, toPosition - 1)
} }
} }
override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean { override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
return dropPosition > 0 return dropPosition > 0
} }
override fun onItemDragStarted(position: Int) { override fun onItemDragStarted(position: Int) {
notifyDataSetChanged() notifyDataSetChanged()
} }
override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) { override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
notifyDataSetChanged() notifyDataSetChanged()
} }
interface OnMoveItemListener { interface OnMoveItemListener {
fun onMoveItem(fromPosition: Int, toPosition: Int) fun onMoveItem(fromPosition: Int, toPosition: Int)
} }
inner class ViewHolder(itemView: View) : PlaylistSongAdapter.ViewHolder(itemView), DraggableItemViewHolder { inner class ViewHolder(itemView: View) : PlaylistSongAdapter.ViewHolder(itemView), DraggableItemViewHolder {
@DraggableItemStateFlags @DraggableItemStateFlags
private var mDragStateFlags: Int = 0 private var mDragStateFlags: Int = 0
override var songMenuRes: Int override var songMenuRes: Int
get() = code.name.monkey.retromusic.R.menu.menu_item_playlist_song get() = code.name.monkey.retromusic.R.menu.menu_item_playlist_song
set(value) { set(value) {
super.songMenuRes = value super.songMenuRes = value
} }
init { init {
if (dragView != null) { if (dragView != null) {
if (onMoveItemListener != null) { if (onMoveItemListener != null) {
dragView?.visibility = View.VISIBLE dragView?.visibility = View.VISIBLE
} else { } else {
dragView?.visibility = View.GONE dragView?.visibility = View.GONE
} }
} }
} }
override fun onSongMenuItemClick(item: MenuItem): Boolean { override fun onSongMenuItemClick(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
code.name.monkey.retromusic.R.id.action_remove_from_playlist -> { code.name.monkey.retromusic.R.id.action_remove_from_playlist -> {
RemoveFromPlaylistDialog.create(song as PlaylistSong) RemoveFromPlaylistDialog.create(song as PlaylistSong)
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST") .show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
return true return true
} }
} }
return super.onSongMenuItemClick(item) return super.onSongMenuItemClick(item)
} }
@DraggableItemStateFlags @DraggableItemStateFlags
override fun getDragStateFlags(): Int { override fun getDragStateFlags(): Int {
return mDragStateFlags return mDragStateFlags
} }
override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) { override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) {
mDragStateFlags = flags mDragStateFlags = flags
} }
} }
companion object { companion object {
val TAG: String = OrderablePlaylistSongAdapter::class.java.simpleName val TAG: String = OrderablePlaylistSongAdapter::class.java.simpleName
} }
} }

View file

@ -1,6 +1,5 @@
package code.name.monkey.retromusic.adapter.song package code.name.monkey.retromusic.adapter.song
import android.graphics.Color
import android.graphics.PorterDuff.Mode import android.graphics.PorterDuff.Mode
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -31,7 +30,7 @@ class PlayingQueueAdapter(
private var current: Int, private var current: Int,
itemLayoutRes: Int itemLayoutRes: Int
) : SongAdapter( ) : SongAdapter(
activity, dataSet, itemLayoutRes, false, null activity, dataSet, itemLayoutRes, null
), DraggableItemAdapter<PlayingQueueAdapter.ViewHolder>, SwipeableItemAdapter<PlayingQueueAdapter.ViewHolder> { ), DraggableItemAdapter<PlayingQueueAdapter.ViewHolder>, SwipeableItemAdapter<PlayingQueueAdapter.ViewHolder> {
private var color = -1 private var color = -1
@ -48,9 +47,6 @@ class PlayingQueueAdapter(
if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) { if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
setAlpha(holder, 0.5f) setAlpha(holder, 0.5f)
} }
if (usePalette) {
setColor(holder, Color.WHITE)
}
} }
private fun setColor(holder: SongAdapter.ViewHolder, white: Int) { private fun setColor(holder: SongAdapter.ViewHolder, white: Int) {
@ -70,12 +66,6 @@ class PlayingQueueAdapter(
} }
} }
override fun usePalette(usePalette: Boolean) {
super.usePalette(usePalette)
this.usePalette = usePalette
notifyDataSetChanged()
}
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
if (position < current) { if (position < current) {
return HISTORY return HISTORY

View file

@ -16,9 +16,8 @@ open class PlaylistSongAdapter(
activity: AppCompatActivity, activity: AppCompatActivity,
dataSet: ArrayList<Song>, dataSet: ArrayList<Song>,
itemLayoutRes: Int, itemLayoutRes: Int,
usePalette: Boolean,
cabHolder: CabHolder? cabHolder: CabHolder?
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder, false) { ) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
init { init {
this.setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection) this.setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection)

View file

@ -7,48 +7,47 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import java.util.* import java.util.ArrayList
class ShuffleButtonSongAdapter( class ShuffleButtonSongAdapter(
activity: AppCompatActivity, activity: AppCompatActivity,
dataSet: ArrayList<Song>, dataSet: ArrayList<Song>,
itemLayoutRes: Int, itemLayoutRes: Int,
usePalette: Boolean, cabHolder: CabHolder?
cabHolder: CabHolder? ) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder) {
override fun createViewHolder(view: View): SongAdapter.ViewHolder { override fun createViewHolder(view: View): SongAdapter.ViewHolder {
return ViewHolder(view) return ViewHolder(view)
} }
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) { override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
if (holder.itemViewType == OFFSET_ITEM) { if (holder.itemViewType == OFFSET_ITEM) {
val viewHolder = holder as ViewHolder val viewHolder = holder as ViewHolder
viewHolder.playAction?.let { viewHolder.playAction?.let {
it.setOnClickListener { it.setOnClickListener {
MusicPlayerRemote.openQueue(dataSet, 0, true) MusicPlayerRemote.openQueue(dataSet, 0, true)
} }
} }
viewHolder.shuffleAction?.let { viewHolder.shuffleAction?.let {
it.setOnClickListener { it.setOnClickListener {
MusicPlayerRemote.openAndShuffleQueue(dataSet, true) MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
} }
} }
} else { } else {
super.onBindViewHolder(holder, position - 1) super.onBindViewHolder(holder, position - 1)
} }
} }
inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) { inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
val playAction: MaterialButton? = itemView.findViewById(R.id.playAction) val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction) val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
override fun onClick(v: View?) { override fun onClick(v: View?) {
if (itemViewType == OFFSET_ITEM) { if (itemViewType == OFFSET_ITEM) {
MusicPlayerRemote.openAndShuffleQueue(dataSet, true) MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
return return
} }
super.onClick(v) super.onClick(v)
} }
} }
} }

View file

@ -6,14 +6,14 @@ import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import java.util.* import java.util.ArrayList
class SimpleSongAdapter( class SimpleSongAdapter(
context: AppCompatActivity, context: AppCompatActivity,
songs: ArrayList<Song>, songs: ArrayList<Song>,
i: Int, layoutRes: Int,
cabHolder: CabHolder? cabHolder: CabHolder?
) : SongAdapter(context, songs, i, false, cabHolder) { ) : SongAdapter(context, songs, layoutRes, cabHolder) {
override fun swapDataSet(dataSet: ArrayList<Song>) { override fun swapDataSet(dataSet: ArrayList<Song>) {
this.dataSet.clear() this.dataSet.clear()

View file

@ -25,7 +25,7 @@ import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialcab.MaterialCab import com.afollestad.materialcab.MaterialCab
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import me.zhanghai.android.fastscroll.PopupTextProvider
import java.util.ArrayList import java.util.ArrayList
/** /**
@ -36,21 +36,17 @@ open class SongAdapter(
protected val activity: AppCompatActivity, protected val activity: AppCompatActivity,
dataSet: ArrayList<Song>, dataSet: ArrayList<Song>,
protected var itemLayoutRes: Int, protected var itemLayoutRes: Int,
usePalette: Boolean,
cabHolder: CabHolder?, cabHolder: CabHolder?,
showSectionName: Boolean = true showSectionName: Boolean = true
) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>( ) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>(
activity, cabHolder, R.menu.menu_media_selection activity, cabHolder, R.menu.menu_media_selection
), MaterialCab.Callback, FastScrollRecyclerView.SectionedAdapter { ), MaterialCab.Callback, PopupTextProvider {
var dataSet: ArrayList<Song> var dataSet: ArrayList<Song>
protected var usePalette = false
private var showSectionName = true private var showSectionName = true
init { init {
this.dataSet = dataSet this.dataSet = dataSet
this.usePalette = usePalette
this.showSectionName = showSectionName this.showSectionName = showSectionName
this.setHasStableIds(true) this.setHasStableIds(true)
} }
@ -60,11 +56,6 @@ open class SongAdapter(
notifyDataSetChanged() notifyDataSetChanged()
} }
open fun usePalette(usePalette: Boolean) {
this.usePalette = usePalette
notifyDataSetChanged()
}
override fun getItemId(position: Int): Long { override fun getItemId(position: Int): Long {
return dataSet[position].id.toLong() return dataSet[position].id.toLong()
} }
@ -113,8 +104,7 @@ open class SongAdapter(
} }
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
if (usePalette) setColors(color, holder) setColors(color, holder)
else setColors(defaultFooterColor, holder)
} }
}) })
} }
@ -143,10 +133,7 @@ open class SongAdapter(
SongsMenuHelper.handleMenuClick(activity, selection, menuItem.itemId) SongsMenuHelper.handleMenuClick(activity, selection, menuItem.itemId)
} }
override fun getSectionName(position: Int): String { override fun getPopupText(position: Int): String {
if (!showSectionName) {
return ""
}
val sectionName: String? = when (PreferenceUtil.getInstance(activity).songSortOrder) { val sectionName: String? = when (PreferenceUtil.getInstance(activity).songSortOrder) {
SortOrder.SongSortOrder.SONG_A_Z, SortOrder.SongSortOrder.SONG_Z_A -> dataSet[position].title SortOrder.SongSortOrder.SONG_A_Z, SortOrder.SongSortOrder.SONG_Z_A -> dataSet[position].title
SortOrder.SongSortOrder.SONG_ALBUM -> dataSet[position].albumName SortOrder.SongSortOrder.SONG_ALBUM -> dataSet[position].albumName
@ -157,6 +144,7 @@ open class SongAdapter(
return "" return ""
} }
} }
println("File name -> $sectionName")
return MusicUtil.getSectionName(sectionName) return MusicUtil.getSectionName(sectionName)
} }

View file

@ -12,10 +12,9 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
private var gridSize: Int = 0 private var gridSize: Int = 0
private var sortOrder: String? = null private var sortOrder: String? = null
private var usePaletteInitialized: Boolean = false
private var usePalette: Boolean = false
private var currentLayoutRes: Int = 0 private var currentLayoutRes: Int = 0
private val isLandscape: Boolean
get() = RetroUtil.isLandscape()
val maxGridSize: Int val maxGridSize: Int
get() = if (isLandscape) { get() = if (isLandscape) {
@ -24,25 +23,24 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
resources.getInteger(R.integer.max_columns) resources.getInteger(R.integer.max_columns)
} }
/** fun itemLayoutRes(): Int {
* Override to customize which item layout currentLayoutRes should be used. You might also want to return if (getGridSize() > maxGridSizeForList) {
* override [.canUsePalette] then. loadLayoutRes()
*
* @see .getGridSize
*/
protected val itemLayoutRes: Int
get() = if (getGridSize() > maxGridSizeForList) {
R.layout.item_grid
} else R.layout.item_list } else R.layout.item_list
}
protected val maxGridSizeForList: Int protected abstract fun setLayoutRes(layoutRes: Int)
fun setAndSaveLayoutRes(layoutRes: Int) {
saveLayoutRes(layoutRes)
setLayoutRes(layoutRes)
}
private val maxGridSizeForList: Int
get() = if (isLandscape) { get() = if (isLandscape) {
activity!!.resources.getInteger(R.integer.default_list_columns_land) activity!!.resources.getInteger(R.integer.default_list_columns_land)
} else activity!!.resources.getInteger(R.integer.default_list_columns) } else activity!!.resources.getInteger(R.integer.default_list_columns)
private val isLandscape: Boolean
get() = RetroUtil.isLandscape()
fun getGridSize(): Int { fun getGridSize(): Int {
if (gridSize == 0) { if (gridSize == 0) {
gridSize = if (isLandscape) { gridSize = if (isLandscape) {
@ -71,19 +69,8 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
setSortOrder(sortOrder) setSortOrder(sortOrder)
} }
/**
* @return whether the palette should be used at all or not
*/
fun usePalette(): Boolean {
if (!usePaletteInitialized) {
usePalette = loadUsePalette()
usePaletteInitialized = true
}
return usePalette
}
fun setAndSaveGridSize(gridSize: Int) { fun setAndSaveGridSize(gridSize: Int) {
val oldLayoutRes = itemLayoutRes val oldLayoutRes = itemLayoutRes()
this.gridSize = gridSize this.gridSize = gridSize
if (isLandscape) { if (isLandscape) {
saveGridSizeLand(gridSize) saveGridSizeLand(gridSize)
@ -91,7 +78,7 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
saveGridSize(gridSize) saveGridSize(gridSize)
} }
// only recreate the adapter and layout manager if the layout currentLayoutRes has changed // only recreate the adapter and layout manager if the layout currentLayoutRes has changed
if (oldLayoutRes != itemLayoutRes) { if (oldLayoutRes != itemLayoutRes()) {
invalidateLayoutManager() invalidateLayoutManager()
invalidateAdapter() invalidateAdapter()
} else { } else {
@ -99,19 +86,6 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
} }
} }
fun setAndSaveUsePalette(usePalette: Boolean) {
this.usePalette = usePalette
saveUsePalette(usePalette)
setUsePalette(usePalette)
}
/**
* @return whether the palette option should be available for the current item layout or not
*/
fun canUsePalette(): Boolean {
return itemLayoutRes == R.layout.item_card_color
}
protected fun notifyLayoutResChanged(@LayoutRes res: Int) { protected fun notifyLayoutResChanged(@LayoutRes res: Int) {
this.currentLayoutRes = res this.currentLayoutRes = res
val recyclerView = recyclerView() val recyclerView = recyclerView()
@ -149,4 +123,8 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
protected abstract fun loadUsePalette(): Boolean protected abstract fun loadUsePalette(): Boolean
protected abstract fun setUsePalette(usePalette: Boolean) protected abstract fun setUsePalette(usePalette: Boolean)
protected abstract fun loadLayoutRes(): Int
protected abstract fun saveLayoutRes(layoutRes: Int)
} }

View file

@ -10,15 +10,16 @@ import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.util.DensityUtil import code.name.monkey.retromusic.util.DensityUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ThemedFastScroller.create
import code.name.monkey.retromusic.views.ScrollingViewOnApplyWindowInsetsListener
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.container import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.container
import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.empty import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.empty
import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.emptyEmoji import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.emptyEmoji
import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.emptyText import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.emptyText
import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.recyclerView import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.recyclerView
import me.everything.android.ui.overscroll.OverScrollDecoratorHelper import me.zhanghai.android.fastscroll.FastScroller
import me.zhanghai.android.fastscroll.FastScrollerBuilder
abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : RecyclerView.LayoutManager> : abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : RecyclerView.LayoutManager> :
AbsLibraryPagerFragment(), AppBarLayout.OnOffsetChangedListener { AbsLibraryPagerFragment(), AppBarLayout.OnOffsetChangedListener {
@ -41,13 +42,21 @@ abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>,
} }
private fun setUpRecyclerView() { private fun setUpRecyclerView() {
if (recyclerView is FastScrollRecyclerView) {
ViewUtil.setUpFastScrollRecyclerViewColor(requireActivity(), recyclerView as FastScrollRecyclerView)
}
recyclerView.layoutManager = layoutManager recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter recyclerView.adapter = adapter
val fastScroller = create(recyclerView)
recyclerView.setOnApplyWindowInsetsListener(
ScrollingViewOnApplyWindowInsetsListener(
recyclerView,
fastScroller
)
)
//OverScrollDecoratorHelper.setUpOverScroll(recyclerView, OverScrollDecoratorHelper.ORIENTATION_VERTICAL)
}
OverScrollDecoratorHelper.setUpOverScroll(recyclerView, OverScrollDecoratorHelper.ORIENTATION_VERTICAL) protected open fun createFastScroller(recyclerView: RecyclerView): FastScroller {
return FastScrollerBuilder(recyclerView).useMd2Style().build()
} }
private fun initAdapter() { private fun initAdapter() {

View file

@ -53,13 +53,13 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
} }
override fun createAdapter(): AlbumAdapter { override fun createAdapter(): AlbumAdapter {
var itemLayoutRes = itemLayoutRes /* var itemLayoutRes = itemLayoutRes
notifyLayoutResChanged(itemLayoutRes) notifyLayoutResChanged(itemLayoutRes)
if (itemLayoutRes != R.layout.item_list) { if (itemLayoutRes != R.layout.item_list) {
itemLayoutRes = PreferenceUtil.getInstance(requireContext()).getAlbumGridStyle(requireContext()) itemLayoutRes = PreferenceUtil.getInstance(requireContext()).getAlbumGridStyle(requireContext())
} }*/
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
return AlbumAdapter(libraryFragment.mainActivity, dataSet, itemLayoutRes, loadUsePalette(), libraryFragment) return AlbumAdapter(libraryFragment.mainActivity, dataSet, itemLayoutRes(), loadUsePalette(), libraryFragment)
} }
public override fun loadUsePalette(): Boolean { public override fun loadUsePalette(): Boolean {
@ -76,37 +76,30 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
} }
override fun loadSortOrder(): String { override fun loadSortOrder(): String {
return PreferenceUtil.getInstance(requireContext()).albumSortOrder return PreferenceUtil.getInstance(requireContext()).albumSortOrder
} }
override fun saveSortOrder(sortOrder: String) { override fun saveSortOrder(sortOrder: String) {
PreferenceUtil.getInstance(requireContext()).albumSortOrder = sortOrder PreferenceUtil.getInstance(requireContext()).albumSortOrder = sortOrder
} }
override fun loadGridSize(): Int { override fun loadGridSize(): Int {
return PreferenceUtil.getInstance(requireContext()).getAlbumGridSize(activity!!) return PreferenceUtil.getInstance(requireContext()).getAlbumGridSize(activity!!)
} }
override fun saveGridSize(gridColumns: Int) { override fun saveGridSize(gridColumns: Int) {
PreferenceUtil.getInstance(requireContext()).setAlbumGridSize(gridColumns) PreferenceUtil.getInstance(requireContext()).setAlbumGridSize(gridColumns)
} }
override fun loadGridSizeLand(): Int { override fun loadGridSizeLand(): Int {
return PreferenceUtil.getInstance(requireContext()).getAlbumGridSizeLand(activity!!) return PreferenceUtil.getInstance(requireContext()).getAlbumGridSizeLand(activity!!)
} }
override fun saveGridSizeLand(gridColumns: Int) { override fun saveGridSizeLand(gridColumns: Int) {
PreferenceUtil.getInstance(requireContext()).setAlbumGridSizeLand(gridColumns) PreferenceUtil.getInstance(requireContext()).setAlbumGridSizeLand(gridColumns)
} }
override fun saveUsePalette(usePalette: Boolean) { override fun saveUsePalette(usePalette: Boolean) {
PreferenceUtil.getInstance(requireContext()).setAlbumColoredFooters(usePalette) PreferenceUtil.getInstance(requireContext()).setAlbumColoredFooters(usePalette)
} }
@ -122,6 +115,18 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
adapter?.swapDataSet(ArrayList()) adapter?.swapDataSet(ArrayList())
} }
override fun setLayoutRes(layoutRes: Int) {
//adapter?.itemCount?.let { adapter?.notifyItemRangeChanged(0, it) }
}
override fun loadLayoutRes(): Int {
return PreferenceUtil.getInstance(requireContext()).albumGridStyle
}
override fun saveLayoutRes(layoutRes: Int) {
PreferenceUtil.getInstance(requireContext()).albumGridStyle = layoutRes
}
companion object { companion object {
@JvmField @JvmField
var TAG: String = AlbumsFragment::class.java.simpleName var TAG: String = AlbumsFragment::class.java.simpleName

View file

@ -61,13 +61,14 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
} }
override fun createAdapter(): ArtistAdapter { override fun createAdapter(): ArtistAdapter {
var itemLayoutRes = itemLayoutRes
notifyLayoutResChanged(itemLayoutRes)
if (itemLayoutRes != R.layout.item_list) {
itemLayoutRes = PreferenceUtil.getInstance(requireContext()).getArtistGridStyle(requireContext())
}
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
return ArtistAdapter(libraryFragment.mainActivity, dataSet, itemLayoutRes, loadUsePalette(), libraryFragment) return ArtistAdapter(
libraryFragment.mainActivity,
dataSet,
itemLayoutRes(),
loadUsePalette(),
libraryFragment
)
} }
override fun loadGridSize(): Int { override fun loadGridSize(): Int {
@ -128,4 +129,15 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
return fragment return fragment
} }
} }
override fun setLayoutRes(layoutRes: Int) {
}
override fun loadLayoutRes(): Int {
return PreferenceUtil.getInstance(requireContext()).artistGridStyle
}
override fun saveLayoutRes(layoutRes: Int) {
PreferenceUtil.getInstance(requireContext()).artistGridStyle = layoutRes
}
} }

View file

@ -35,7 +35,6 @@ import code.name.monkey.retromusic.util.RetroUtil;
import com.afollestad.materialcab.MaterialCab; import com.afollestad.materialcab.MaterialCab;
import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.card.MaterialCardView; import com.google.android.material.card.MaterialCardView;
import io.reactivex.disposables.CompositeDisposable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class LibraryFragment extends AbsMainActivityFragment implements CabHolder, MainActivityFragmentCallbacks { public class LibraryFragment extends AbsMainActivityFragment implements CabHolder, MainActivityFragmentCallbacks {
@ -48,8 +47,6 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
private MaterialCab cab; private MaterialCab cab;
private CompositeDisposable disposable;
private FragmentManager fragmentManager; private FragmentManager fragmentManager;
private Toolbar toolbar; private Toolbar toolbar;
@ -76,7 +73,6 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
@Nullable ViewGroup container, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_library, container, false); View view = inflater.inflate(R.layout.fragment_library, container, false);
disposable = new CompositeDisposable();
appBarLayout = view.findViewById(R.id.appBarLayout); appBarLayout = view.findViewById(R.id.appBarLayout);
toolbarContainer = view.findViewById(R.id.toolbarContainer); toolbarContainer = view.findViewById(R.id.toolbarContainer);
toolbar = view.findViewById(R.id.toolbar); toolbar = view.findViewById(R.id.toolbar);
@ -91,11 +87,6 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
inflateFragment(); inflateFragment();
} }
@Override
public void onDestroyView() {
super.onDestroyView();
disposable.dispose();
}
public void addOnAppBarOffsetChangedListener( public void addOnAppBarOffsetChangedListener(
@NonNull AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) { @NonNull AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) {
@ -126,11 +117,18 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment
= (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment; = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment;
MenuItem gridSizeItem = menu.findItem(R.id.action_grid_size); if (fragment instanceof SongsFragment) {
if (RetroUtil.isLandscape()) { menu.removeItem(R.id.action_grid_size);
gridSizeItem.setTitle(R.string.action_grid_size_land); menu.removeItem(R.id.action_layout_type);
} else {
MenuItem gridSizeItem = menu.findItem(R.id.action_grid_size);
if (RetroUtil.isLandscape()) {
gridSizeItem.setTitle(R.string.action_grid_size_land);
}
setUpGridSizeMenu(fragment, gridSizeItem.getSubMenu());
MenuItem layoutItem = menu.findItem(R.id.action_layout_type);
setupLayoutMenu(fragment, layoutItem.getSubMenu());
} }
setUpGridSizeMenu(fragment, gridSizeItem.getSubMenu());
setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).getSubMenu()); setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).getSubMenu());
@ -157,6 +155,9 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
if (handleGridSizeMenuItem(fragment, item)) { if (handleGridSizeMenuItem(fragment, item)) {
return true; return true;
} }
if (handleLayoutResType(fragment, item)) {
return true;
}
if (handleSortOrderMenuItem(fragment, item)) { if (handleSortOrderMenuItem(fragment, item)) {
return true; return true;
} }
@ -220,8 +221,8 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
} }
private boolean handleGridSizeMenuItem( private boolean handleGridSizeMenuItem(
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment,
fragment, @NonNull MenuItem item) { @NonNull MenuItem item) {
int gridSize = 0; int gridSize = 0;
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_grid_size_1: case R.id.action_grid_size_1:
@ -258,6 +259,38 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
return false; return false;
} }
private boolean handleLayoutResType(
final AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment,
final MenuItem item) {
int layoutRes = -1;
switch (item.getItemId()) {
case R.id.action_layout_normal:
layoutRes = R.layout.item_grid;
break;
case R.id.action_layout_card:
layoutRes = R.layout.item_card;
break;
case R.id.action_layout_colored_card:
layoutRes = R.layout.item_card_color;
break;
case R.id.action_layout_circular:
layoutRes = R.layout.item_grid_circle;
break;
case R.id.action_layout_image:
layoutRes = R.layout.image;
break;
case R.id.action_layout_gradient_image:
layoutRes = R.layout.item_image_gradient;
break;
}
if (layoutRes != -1) {
item.setChecked(true);
fragment.setAndSaveLayoutRes(layoutRes);
return true;
}
return false;
}
private boolean handleSortOrderMenuItem( private boolean handleSortOrderMenuItem(
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment
fragment, @NonNull MenuItem item) { fragment, @NonNull MenuItem item) {
@ -448,7 +481,31 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
sortOrderMenu.setGroupCheckable(0, true, true); sortOrderMenu.setGroupCheckable(0, true, true);
} }
@SuppressWarnings("ConstantConditions") private void setupLayoutMenu(
@NonNull final AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment,
@NonNull final SubMenu subMenu) {
switch (fragment.itemLayoutRes()) {
case R.layout.item_card:
subMenu.findItem(R.id.action_layout_card).setChecked(true);
break;
case R.layout.item_grid:
subMenu.findItem(R.id.action_layout_normal).setChecked(true);
break;
case R.layout.item_card_color:
subMenu.findItem(R.id.action_layout_colored_card).setChecked(true);
break;
case R.layout.item_grid_circle:
subMenu.findItem(R.id.action_layout_circular).setChecked(true);
break;
case R.layout.image:
subMenu.findItem(R.id.action_layout_image).setChecked(true);
break;
case R.layout.item_image_gradient:
subMenu.findItem(R.id.action_layout_gradient_image).setChecked(true);
break;
}
}
private void setupToolbar() { private void setupToolbar() {
toolbar.setBackgroundTintList( toolbar.setBackgroundTintList(
ColorStateList.valueOf(ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorSurface))); ColorStateList.valueOf(ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorSurface)));
@ -462,6 +519,5 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
getMainActivity().setSupportActionBar(toolbar); getMainActivity().setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(v -> showMainMenu(OptionsSheetDialogFragment.LIBRARY)); toolbar.setNavigationOnClickListener(v -> showMainMenu(OptionsSheetDialogFragment.LIBRARY));
ToolbarContentTintHelper.colorBackButton(toolbar); ToolbarContentTintHelper.colorBackButton(toolbar);
//toolbar.setTitleTextColor(ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorOnSecondary));
} }
} }

View file

@ -2,7 +2,8 @@ package code.name.monkey.retromusic.fragments.mainactivity
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.recyclerview.widget.GridLayoutManager import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter
@ -12,15 +13,15 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.mvp.presenter.SongPresenter import code.name.monkey.retromusic.mvp.presenter.SongPresenter
import code.name.monkey.retromusic.mvp.presenter.SongView import code.name.monkey.retromusic.mvp.presenter.SongView
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import java.util.* import java.util.ArrayList
import javax.inject.Inject import javax.inject.Inject
class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager>(), SongView { class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdapter, LinearLayoutManager>(),
SongView {
@Inject @Inject
lateinit var songPresenter: SongPresenter lateinit var songPresenter: SongPresenter
override val emptyMessage: Int override val emptyMessage: Int
get() = R.string.no_songs get() = R.string.no_songs
@ -34,20 +35,18 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
songPresenter.attachView(this) songPresenter.attachView(this)
} }
override fun createLayoutManager(): GridLayoutManager { override fun createLayoutManager(): LinearLayoutManager {
return GridLayoutManager(activity, getGridSize()) return LinearLayoutManager(activity)
} }
override fun createAdapter(): SongAdapter { override fun createAdapter(): SongAdapter {
val itemLayoutRes = itemLayoutRes
notifyLayoutResChanged(itemLayoutRes)
val usePalette = loadUsePalette()
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
return ShuffleButtonSongAdapter(
return if (getGridSize() <= maxGridSizeForList) { libraryFragment.mainActivity,
ShuffleButtonSongAdapter(libraryFragment.mainActivity, dataSet, itemLayoutRes, usePalette, libraryFragment) dataSet,
} else SongAdapter(libraryFragment.mainActivity, dataSet, itemLayoutRes, usePalette, libraryFragment) R.layout.item_list,
libraryFragment
)
} }
override fun songs(songs: ArrayList<Song>) { override fun songs(songs: ArrayList<Song>) {
@ -83,11 +82,9 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
} }
public override fun setUsePalette(usePalette: Boolean) { public override fun setUsePalette(usePalette: Boolean) {
adapter?.usePalette(usePalette)
} }
override fun setGridSize(gridSize: Int) { override fun setGridSize(gridSize: Int) {
layoutManager?.spanCount = gridSize
adapter?.notifyDataSetChanged() adapter?.notifyDataSetChanged()
} }
@ -131,4 +128,15 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
return fragment return fragment
} }
} }
override fun setLayoutRes(@LayoutRes layoutRes: Int) {
}
@LayoutRes
override fun loadLayoutRes(): Int {
return R.layout.item_list
}
override fun saveLayoutRes(@LayoutRes layoutRes: Int) {
}
} }

View file

@ -111,6 +111,7 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment(), OnSharedPref
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
title.text = song.title title.text = song.title
text.text = song.artistName text.text = song.artistName
if (PreferenceUtil.getInstance(requireContext()).isSongInfo) { if (PreferenceUtil.getInstance(requireContext()).isSongInfo) {
songInfo?.text = getSongInfo(song) songInfo?.text = getSongInfo(song)
} else { } else {
@ -266,7 +267,7 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment(), OnSharedPref
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
println(key) println(key)
if (key == PreferenceUtil.EXTRA_SONG_INFO) { if (key == PreferenceUtil.EXTRA_SONG_INFO) {
updateSong() if (activity != null) updateSong()
} }
} }

View file

@ -41,11 +41,7 @@ class PersonalizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnS
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
PreferenceUtil.getInstance(requireContext()).registerOnSharedPreferenceChangedListener(this) PreferenceUtil.getInstance(requireContext()).registerOnSharedPreferenceChangedListener(this)
var preference: Preference? = findPreference("album_grid_style") var preference: Preference? = findPreference("home_artist_grid_style")
setSummary(preference!!)
preference = findPreference("artist_grid_style")
setSummary(preference!!)
preference = findPreference("home_artist_grid_style")
setSummary(preference!!) setSummary(preference!!)
preference = findPreference("tab_text_mode") preference = findPreference("tab_text_mode")
setSummary(preference!!) setSummary(preference!!)

View file

@ -16,7 +16,12 @@ package code.name.monkey.retromusic.helper
import android.annotation.TargetApi import android.annotation.TargetApi
import android.app.Activity import android.app.Activity
import android.content.* import android.content.ComponentName
import android.content.ContentResolver
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.ServiceConnection
import android.database.Cursor import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
@ -32,8 +37,9 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import java.io.File import java.io.File
import java.util.* import java.util.ArrayList
import java.util.Random
import java.util.WeakHashMap
object MusicPlayerRemote { object MusicPlayerRemote {
val TAG: String = MusicPlayerRemote::class.java.simpleName val TAG: String = MusicPlayerRemote::class.java.simpleName
@ -116,7 +122,12 @@ object MusicPlayerRemote {
} }
val binder = ServiceBinder(callback) val binder = ServiceBinder(callback)
if (contextWrapper.bindService(Intent().setClass(contextWrapper, MusicService::class.java), binder, Context.BIND_AUTO_CREATE)) { if (contextWrapper.bindService(
Intent().setClass(contextWrapper, MusicService::class.java),
binder,
Context.BIND_AUTO_CREATE
)
) {
mConnectionMap[contextWrapper] = binder mConnectionMap[contextWrapper] = binder
return ServiceToken(contextWrapper) return ServiceToken(contextWrapper)
} }
@ -234,7 +245,11 @@ object MusicPlayerRemote {
} }
} }
private fun tryToHandleOpenPlayingQueue(queue: ArrayList<Song>, startPosition: Int, startPlaying: Boolean): Boolean { private fun tryToHandleOpenPlayingQueue(
queue: ArrayList<Song>,
startPosition: Int,
startPlaying: Boolean
): Boolean {
if (playingQueue === queue) { if (playingQueue === queue) {
if (startPlaying) { if (startPlaying) {
playSongAt(startPosition) playSongAt(startPosition)
@ -291,7 +306,11 @@ object MusicPlayerRemote {
queue.add(song) queue.add(song)
openQueue(queue, 0, false) openQueue(queue, 0, false)
} }
Toast.makeText(musicService, musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_title_to_playing_queue), Toast.LENGTH_SHORT).show() Toast.makeText(
musicService,
musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_title_to_playing_queue),
Toast.LENGTH_SHORT
).show()
return true return true
} }
return false return false
@ -304,7 +323,11 @@ object MusicPlayerRemote {
} else { } else {
openQueue(songs, 0, false) openQueue(songs, 0, false)
} }
val toast = if (songs.size == 1) musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_title_to_playing_queue) else musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_x_titles_to_playing_queue, songs.size) val toast =
if (songs.size == 1) musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_title_to_playing_queue) else musicService!!.resources.getString(
code.name.monkey.retromusic.R.string.added_x_titles_to_playing_queue,
songs.size
)
Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show() Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show()
return true return true
} }
@ -320,7 +343,11 @@ object MusicPlayerRemote {
queue.add(song) queue.add(song)
openQueue(queue, 0, false) openQueue(queue, 0, false)
} }
Toast.makeText(musicService, musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_title_to_playing_queue), Toast.LENGTH_SHORT).show() Toast.makeText(
musicService,
musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_title_to_playing_queue),
Toast.LENGTH_SHORT
).show()
return true return true
} }
return false return false
@ -333,7 +360,11 @@ object MusicPlayerRemote {
} else { } else {
openQueue(songs, 0, false) openQueue(songs, 0, false)
} }
val toast = if (songs.size == 1) musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_title_to_playing_queue) else musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_x_titles_to_playing_queue, songs.size) val toast =
if (songs.size == 1) musicService!!.resources.getString(code.name.monkey.retromusic.R.string.added_title_to_playing_queue) else musicService!!.resources.getString(
code.name.monkey.retromusic.R.string.added_x_titles_to_playing_queue,
songs.size
)
Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show() Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show()
return true return true
} }
@ -385,18 +416,21 @@ object MusicPlayerRemote {
songId = uri.lastPathSegment songId = uri.lastPathSegment
} }
if (songId != null) { if (songId != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor( songs = SongLoader.getSongs(
SongLoader.makeSongCursor(
musicService!!, musicService!!,
MediaStore.Audio.AudioColumns._ID + "=?", MediaStore.Audio.AudioColumns._ID + "=?",
arrayOf(songId) arrayOf(songId)
)) )
)
} }
} }
} }
if (songs == null) { if (songs == null) {
var songFile: File? = null var songFile: File? = null
if (uri.authority != null && uri.authority == "com.android.externalstorage.documents") { if (uri.authority != null && uri.authority == "com.android.externalstorage.documents") {
songFile = File(Environment.getExternalStorageDirectory(), uri.path?.split(":".toRegex(), 2)?.get(1)) songFile =
File(Environment.getExternalStorageDirectory(), uri.path?.split(":".toRegex(), 2)?.get(1))
} }
if (songFile == null) { if (songFile == null) {
val path = getFilePathFromUri(musicService!!, uri) val path = getFilePathFromUri(musicService!!, uri)
@ -407,11 +441,13 @@ object MusicPlayerRemote {
songFile = File(uri.path) songFile = File(uri.path)
} }
if (songFile != null) { if (songFile != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor( songs = SongLoader.getSongs(
SongLoader.makeSongCursor(
musicService!!, musicService!!,
MediaStore.Audio.AudioColumns.DATA + "=?", MediaStore.Audio.AudioColumns.DATA + "=?",
arrayOf(songFile.absolutePath) arrayOf(songFile.absolutePath)
)) )
)
} }
} }
if (songs != null && songs.isNotEmpty()) { if (songs != null && songs.isNotEmpty()) {
@ -442,5 +478,4 @@ object MusicPlayerRemote {
} }
class ServiceToken internal constructor(internal var mWrappedContext: ContextWrapper) class ServiceToken internal constructor(internal var mWrappedContext: ContextWrapper)
} }

View file

@ -112,7 +112,7 @@ public class MusicUtil {
@NonNull @NonNull
public static String getPlaylistInfoString(@NonNull final Context context, @NonNull List<Song> songs) { public static String getPlaylistInfoString(@NonNull final Context context, @NonNull List<Song> songs) {
final long duration = getTotalDuration(context, songs); final long duration = getTotalDuration(songs);
return MusicUtil.buildInfoString( return MusicUtil.buildInfoString(
MusicUtil.getSongCountString(context, songs.size()), MusicUtil.getSongCountString(context, songs.size()),
@ -388,7 +388,7 @@ public class MusicUtil {
if (musicMediaTitle.isEmpty()) { if (musicMediaTitle.isEmpty()) {
return ""; return "";
} }
return String.valueOf(musicMediaTitle.charAt(0)).toUpperCase(); return musicMediaTitle.substring(0, 1).toUpperCase();
} }
@NonNull @NonNull
@ -400,7 +400,7 @@ public class MusicUtil {
MusicUtil.playlist = playlist; MusicUtil.playlist = playlist;
} }
public static long getTotalDuration(@NonNull final Context context, @NonNull List<Song> songs) { public static long getTotalDuration(@NonNull List<Song> songs) {
long duration = 0; long duration = 0;
for (int i = 0; i < songs.size(); i++) { for (int i = 0; i < songs.size(); i++) {
duration += songs.get(i).getDuration(); duration += songs.get(i).getDuration();
@ -408,7 +408,7 @@ public class MusicUtil {
return duration; return duration;
} }
public static int indexOfSongInList(List<Song> songs, int songId) { public static int indexOfSongInList(@NonNull List<Song> songs, int songId) {
for (int i = 0; i < songs.size(); i++) { for (int i = 0; i < songs.size(); i++) {
if (songs.get(i).getId() == songId) { if (songs.get(i).getId() == songId) {
return i; return i;

View file

@ -28,7 +28,6 @@ import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.StyleRes; import androidx.annotation.StyleRes;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.activities.MainActivity; import code.name.monkey.retromusic.activities.MainActivity;
import code.name.monkey.retromusic.fragments.AlbumCoverStyle; import code.name.monkey.retromusic.fragments.AlbumCoverStyle;
@ -118,11 +117,11 @@ public final class PreferenceUtil {
public static final String TOGGLE_SEPARATE_LINE = "toggle_separate_line"; public static final String TOGGLE_SEPARATE_LINE = "toggle_separate_line";
public static final String ALBUM_GRID_STYLE = "album_grid_style"; public static final String ALBUM_GRID_STYLE = "album_grid_style_home";
public static final String HOME_ARTIST_GRID_STYLE = "home_artist_grid_style"; public static final String HOME_ARTIST_GRID_STYLE = "home_artist_grid_style";
public static final String ARTIST_GRID_STYLE = "artist_grid_style"; public static final String ARTIST_GRID_STYLE = "artist_grid_style_home";
public static final String TOGGLE_ADD_CONTROLS = "toggle_add_controls"; public static final String TOGGLE_ADD_CONTROLS = "toggle_add_controls";
@ -233,7 +232,7 @@ public final class PreferenceUtil {
@NonNull @NonNull
public static PreferenceUtil getInstance(Context context) { public static PreferenceUtil getInstance(Context context) {
if (sInstance == null) { if (sInstance == null) {
sInstance = new PreferenceUtil(App.Companion.getContext()); sInstance = new PreferenceUtil(context);
} }
return sInstance; return sInstance;
} }
@ -249,7 +248,7 @@ public final class PreferenceUtil {
} }
} }
public static boolean isAllowedToDownloadMetadata(final Context context) { public static boolean isAllowedToDownloadMetadata(@NonNull Context context) {
switch (getInstance(context).autoDownloadImagesPolicy()) { switch (getInstance(context).autoDownloadImagesPolicy()) {
case "always": case "always":
return true; return true;
@ -392,26 +391,25 @@ public final class PreferenceUtil {
return layoutRes; return layoutRes;
} }
public final int getAlbumGridSize(Context context) { public final int getAlbumGridSize(@NonNull Context context) {
return mPreferences return mPreferences
.getInt(ALBUM_GRID_SIZE, context.getResources().getInteger(R.integer.default_grid_columns)); .getInt(ALBUM_GRID_SIZE, context.getResources().getInteger(R.integer.default_grid_columns));
} }
public final int getAlbumGridSizeLand(Context context) { public final int getAlbumGridSizeLand(@NonNull Context context) {
return mPreferences.getInt(ALBUM_GRID_SIZE_LAND, return mPreferences
context.getResources().getInteger(R.integer.default_grid_columns_land)); .getInt(ALBUM_GRID_SIZE_LAND, context.getResources().getInteger(R.integer.default_grid_columns_land));
} }
@LayoutRes @LayoutRes
public int getAlbumGridStyle(Context context) { public int getAlbumGridStyle() {
int pos = Integer.parseInt(mPreferences.getString(ALBUM_GRID_STYLE, "0")); return mPreferences.getInt(ALBUM_GRID_STYLE, R.layout.item_grid);
TypedArray typedArray = context.getResources().obtainTypedArray(R.array.pref_grid_style_layout); }
int layoutRes = typedArray.getResourceId(pos, -1);
typedArray.recycle(); public void setAlbumGridStyle(int layoutRes) {
if (layoutRes == -1) { mPreferences.edit()
return R.layout.item_card; .putInt(ALBUM_GRID_STYLE, layoutRes)
} .apply();
return layoutRes;
} }
public final String getAlbumSongSortOrder() { public final String getAlbumSongSortOrder() {
@ -455,15 +453,12 @@ public final class PreferenceUtil {
} }
@LayoutRes @LayoutRes
public int getArtistGridStyle(Context context) { public int getArtistGridStyle() {
int pos = Integer.parseInt(Objects.requireNonNull(mPreferences.getString(ARTIST_GRID_STYLE, "0"))); return mPreferences.getInt(ARTIST_GRID_STYLE, R.layout.item_grid);
TypedArray typedArray = context.getResources().obtainTypedArray(R.array.pref_grid_style_layout); }
int layoutRes = typedArray.getResourceId(pos, -1);
typedArray.recycle(); public void setArtistGridStyle(int viewAs) {
if (layoutRes == -1) { mPreferences.edit().putInt(ARTIST_GRID_STYLE, viewAs).apply();
return R.layout.item_card;
}
return layoutRes;
} }
public final String getArtistSongSortOrder() { public final String getArtistSongSortOrder() {
@ -699,10 +694,6 @@ public final class PreferenceUtil {
return mPreferences.getBoolean(SLEEP_TIMER_FINISH_SONG, false); return mPreferences.getBoolean(SLEEP_TIMER_FINISH_SONG, false);
} }
public boolean isSongInfo() {
return mPreferences.getBoolean(EXTRA_SONG_INFO, false);
}
public void setSleepTimerFinishMusic(final boolean value) { public void setSleepTimerFinishMusic(final boolean value) {
final SharedPreferences.Editor editor = mPreferences.edit(); final SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(SLEEP_TIMER_FINISH_SONG, value); editor.putBoolean(SLEEP_TIMER_FINISH_SONG, value);
@ -836,6 +827,10 @@ public final class PreferenceUtil {
return mPreferences.getBoolean(SNOW_FALL_EFFECT, false); return mPreferences.getBoolean(SNOW_FALL_EFFECT, false);
} }
public boolean isSongInfo() {
return mPreferences.getBoolean(EXTRA_SONG_INFO, false);
}
public boolean pauseOnZeroVolume() { public boolean pauseOnZeroVolume() {
return mPreferences.getBoolean(PAUSE_ON_ZERO_VOLUME, false); return mPreferences.getBoolean(PAUSE_ON_ZERO_VOLUME, false);
} }
@ -899,10 +894,6 @@ public final class PreferenceUtil {
editor.apply(); editor.apply();
} }
public void setArtistGridStyle(int viewAs) {
mPreferences.edit().putInt(ARTIST_GRID_STYLE, viewAs).apply();
}
public void setBannerImagePath(String bannerImagePath) { public void setBannerImagePath(String bannerImagePath) {
mPreferences.edit().putString(BANNER_IMAGE_PATH, bannerImagePath) mPreferences.edit().putString(BANNER_IMAGE_PATH, bannerImagePath)
.apply(); .apply();
@ -980,17 +971,6 @@ public final class PreferenceUtil {
return mPreferences.getBoolean(SONG_COLORED_FOOTERS, false); return mPreferences.getBoolean(SONG_COLORED_FOOTERS, false);
} }
public final boolean synchronizedLyricsShow() {
return mPreferences.getBoolean(SYNCHRONIZED_LYRICS_SHOW, true);
}
public boolean tabTitles() {
return getTabTitleMode() != LabelVisibilityMode.LABEL_VISIBILITY_UNLABELED;
}
public boolean toggleSeparateLine() {
return mPreferences.getBoolean(TOGGLE_SEPARATE_LINE, false);
}
public void unregisterOnSharedPreferenceChangedListener( public void unregisterOnSharedPreferenceChangedListener(
@NonNull OnSharedPreferenceChangeListener sharedPreferenceChangeListener) { @NonNull OnSharedPreferenceChangeListener sharedPreferenceChangeListener) {

View file

@ -19,25 +19,27 @@ import android.content.res.TypedArray;
import android.graphics.Paint; import android.graphics.Paint;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.TypedValue; import android.util.TypedValue;
import androidx.annotation.FontRes; import androidx.annotation.FontRes;
import com.google.android.material.textview.MaterialTextView;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import com.google.android.material.textview.MaterialTextView;
public class BaselineGridTextView extends MaterialTextView { public class BaselineGridTextView extends MaterialTextView {
private final float FOUR_DIP; private final float FOUR_DIP;
private float lineHeightMultiplierHint = 1f;
private float lineHeightHint = 0f;
private boolean maxLinesByHeight = false;
private int extraTopPadding = 0;
private int extraBottomPadding = 0; private int extraBottomPadding = 0;
private int extraTopPadding = 0;
private @FontRes private @FontRes
int fontResId = 0; int fontResId = 0;
private float lineHeightHint = 0f;
private float lineHeightMultiplierHint = 1f;
private boolean maxLinesByHeight = false;
public BaselineGridTextView(Context context) { public BaselineGridTextView(Context context) {
this(context, null); this(context, null);
} }
@ -73,13 +75,21 @@ public class BaselineGridTextView extends MaterialTextView {
computeLineHeight(); computeLineHeight();
} }
public float getLineHeightMultiplierHint() { @Override
return lineHeightMultiplierHint; public int getCompoundPaddingBottom() {
// include extra padding to make the height a multiple of 4dp
return super.getCompoundPaddingBottom() + extraBottomPadding;
} }
public void setLineHeightMultiplierHint(float lineHeightMultiplierHint) { @Override
this.lineHeightMultiplierHint = lineHeightMultiplierHint; public int getCompoundPaddingTop() {
computeLineHeight(); // include extra padding to place the first line's baseline on the grid
return super.getCompoundPaddingTop() + extraTopPadding;
}
public @FontRes
int getFontResId() {
return fontResId;
} }
public float getLineHeightHint() { public float getLineHeightHint() {
@ -91,6 +101,15 @@ public class BaselineGridTextView extends MaterialTextView {
computeLineHeight(); computeLineHeight();
} }
public float getLineHeightMultiplierHint() {
return lineHeightMultiplierHint;
}
public void setLineHeightMultiplierHint(float lineHeightMultiplierHint) {
this.lineHeightMultiplierHint = lineHeightMultiplierHint;
computeLineHeight();
}
public boolean getMaxLinesByHeight() { public boolean getMaxLinesByHeight() {
return maxLinesByHeight; return maxLinesByHeight;
} }
@ -100,23 +119,6 @@ public class BaselineGridTextView extends MaterialTextView {
requestLayout(); requestLayout();
} }
public @FontRes
int getFontResId() {
return fontResId;
}
@Override
public int getCompoundPaddingTop() {
// include extra padding to place the first line's baseline on the grid
return super.getCompoundPaddingTop() + extraTopPadding;
}
@Override
public int getCompoundPaddingBottom() {
// include extra padding to make the height a multiple of 4dp
return super.getCompoundPaddingBottom() + extraBottomPadding;
}
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
extraTopPadding = 0; extraTopPadding = 0;
@ -129,18 +131,18 @@ public class BaselineGridTextView extends MaterialTextView {
checkMaxLines(height, MeasureSpec.getMode(heightMeasureSpec)); checkMaxLines(height, MeasureSpec.getMode(heightMeasureSpec));
} }
private void parseTextAttrs(TypedArray a) { /**
if (a.hasValue(R.styleable.BaselineGridTextView_lineHeightMultiplierHint)) { * When measured with an exact height, text can be vertically clipped mid-line. Prevent
lineHeightMultiplierHint = * this by setting the {@code maxLines} property based on the available space.
a.getFloat(R.styleable.BaselineGridTextView_lineHeightMultiplierHint, 1f); */
} private void checkMaxLines(int height, int heightMode) {
if (a.hasValue(R.styleable.BaselineGridTextView_lineHeightHint)) { if (!maxLinesByHeight || heightMode != MeasureSpec.EXACTLY) {
lineHeightHint = a.getDimensionPixelSize( return;
R.styleable.BaselineGridTextView_lineHeightHint, 0);
}
if (a.hasValue(R.styleable.BaselineGridTextView_android_fontFamily)) {
fontResId = a.getResourceId(R.styleable.BaselineGridTextView_android_fontFamily, 0);
} }
int textHeight = height - getCompoundPaddingTop() - getCompoundPaddingBottom();
int completeLines = (int) Math.floor(textHeight / getLineHeight());
setMaxLines(completeLines);
} }
/** /**
@ -181,15 +183,17 @@ public class BaselineGridTextView extends MaterialTextView {
return extraBottomPadding; return extraBottomPadding;
} }
/** private void parseTextAttrs(TypedArray a) {
* When measured with an exact height, text can be vertically clipped mid-line. Prevent if (a.hasValue(R.styleable.BaselineGridTextView_lineHeightMultiplierHint)) {
* this by setting the {@code maxLines} property based on the available space. lineHeightMultiplierHint =
*/ a.getFloat(R.styleable.BaselineGridTextView_lineHeightMultiplierHint, 1f);
private void checkMaxLines(int height, int heightMode) { }
if (!maxLinesByHeight || heightMode != MeasureSpec.EXACTLY) return; if (a.hasValue(R.styleable.BaselineGridTextView_lineHeightHint)) {
lineHeightHint = a.getDimensionPixelSize(
int textHeight = height - getCompoundPaddingTop() - getCompoundPaddingBottom(); R.styleable.BaselineGridTextView_lineHeightHint, 0);
int completeLines = (int) Math.floor(textHeight / getLineHeight()); }
setMaxLines(completeLines); if (a.hasValue(R.styleable.BaselineGridTextView_android_fontFamily)) {
fontResId = a.getResourceId(R.styleable.BaselineGridTextView_android_fontFamily, 0);
}
} }
} }

View file

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:orientation="vertical" android:orientation="vertical"
tools:ignore="UnusedAttribute"> tools:ignore="UnusedAttribute">
@ -16,8 +17,7 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:background="?attr/colorSurface">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout" android:id="@+id/appBarLayout"

View file

@ -80,7 +80,7 @@
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View file

@ -67,7 +67,7 @@
app:contentInsetStart="0dp" app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp" app:contentInsetStartWithNavigation="0dp"
app:popupTheme="?attr/toolbarPopupTheme" app:popupTheme="?attr/toolbarPopupTheme"
app:title="@string/search_hint" app:title="@string/action_search"
app:titleMarginStart="0dp" app:titleMarginStart="0dp"
app:titleTextAppearance="@style/ToolbarTextAppearanceSearch" app:titleTextAppearance="@style/ToolbarTextAppearanceSearch"
app:titleTextColor="?android:attr/textColorSecondary" app:titleTextColor="?android:attr/textColorSecondary"

View file

@ -6,14 +6,15 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipToPadding="false" android:clipToPadding="false"
android:layoutAnimation="@anim/layout_animation_fall_down" android:layoutAnimation="@anim/layout_animation_fall_down"
android:scrollbars="none" android:scrollbars="none"
app:layout_dodgeInsetEdges="bottom" /> app:layout_dodgeInsetEdges="bottom"
tools:listitem="@layout/item_list" />
<LinearLayout <LinearLayout
android:id="@android:id/empty" android:id="@android:id/empty"

View file

@ -15,7 +15,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:gravity="center"
android:minWidth="40dp" android:minWidth="40dp"
android:singleLine="true" android:singleLine="true"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
@ -31,8 +30,8 @@
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal" style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="8"
android:maxHeight="3dp" android:maxHeight="3dp"
android:padding="0dp"
android:progressDrawable="@drawable/color_progress_seek" android:progressDrawable="@drawable/color_progress_seek"
android:splitTrack="false" android:splitTrack="false"
android:thumb="@drawable/switch_thumb_material" android:thumb="@drawable/switch_thumb_material"
@ -47,7 +46,7 @@
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:gravity="center" android:gravity="end"
android:minWidth="40dp" android:minWidth="40dp"
android:singleLine="true" android:singleLine="true"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"

View file

@ -26,8 +26,7 @@
<menu> <menu>
<group <group
android:id="@+id/group_grid_size" android:id="@+id/group_grid_size"
android:checkableBehavior="single" android:checkableBehavior="single">
tools:ignore="HardcodedText">
<item <item
android:id="@+id/action_grid_size_1" android:id="@+id/action_grid_size_1"
android:title="@string/grid_size_1" /> android:title="@string/grid_size_1" />
@ -55,12 +54,41 @@
</group> </group>
</menu> </menu>
</item> </item>
<item
android:id="@+id/action_layout_type"
android:icon="@drawable/ic_grid_size_white_24dp"
android:title="@string/grid_style_label"
app:showAsAction="never">
<menu>
<group
android:id="@+id/group_layout_type"
android:checkableBehavior="single">
<item
android:id="@+id/action_layout_normal"
android:title="@string/normal" />
<item
android:id="@+id/action_layout_card"
android:title="@string/card" />
<item
android:id="@+id/action_layout_colored_card"
android:title="@string/card_color_style" />
<item
android:id="@+id/action_layout_circular"
android:title="@string/circular" />
<item
android:id="@+id/action_layout_image"
android:title="@string/image" />
<item
android:id="@+id/action_layout_gradient_image"
android:title="@string/image_gradient" />
</group>
</menu>
</item>
<item <item
android:id="@+id/action_sort_order" android:id="@+id/action_sort_order"
android:icon="@drawable/ic_sort_white_24dp" android:icon="@drawable/ic_sort_white_24dp"
android:title="@string/action_sort_order" android:title="@string/action_sort_order"
app:showAsAction="never"> app:showAsAction="ifRoom">
<menu></menu> <menu></menu>
</item> </item>

View file

@ -8,6 +8,13 @@
android:title="@string/pref_title_now_playing_screen_appearance" android:title="@string/pref_title_now_playing_screen_appearance"
app:icon="@drawable/ic_play_circle_filled_white_24dp" /> app:icon="@drawable/ic_play_circle_filled_white_24dp" />
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
android:defaultValue="false"
android:key="extra_song_info"
android:layout="@layout/list_item_view_switch"
android:summary="@string/pref_summary_extra_song_info"
android:title="@string/pref_title_extra_song_info" />
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory <code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory
android:layout="@layout/preference_category_title" android:layout="@layout/preference_category_title"
android:title="@string/pref_header_album"> android:title="@string/pref_header_album">

View file

@ -3,29 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory <code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory
android:layout="@layout/preference_category_title" android:layout="@layout/preference_category_title"
app:title="@string/grid_style_label"> app:title="@string/home">
<code.name.monkey.retromusic.preferences.MaterialListPreference
android:defaultValue="0"
android:entries="@array/pref_grid_style_list_titles"
android:entryValues="@array/pref_grid_style_list_values"
android:key="album_grid_style"
android:layout="@layout/list_item_view"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="@string/pref_title_album_grid_style"
app:icon="@drawable/ic_album_white_24dp" />
<code.name.monkey.retromusic.preferences.MaterialListPreference
android:defaultValue="0"
android:entries="@array/pref_grid_style_list_titles"
android:entryValues="@array/pref_grid_style_list_values"
android:key="artist_grid_style"
android:layout="@layout/list_item_view"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="@string/pref_title_artist_grid_style"
app:icon="@drawable/ic_artist_white_24dp" />
<code.name.monkey.retromusic.preferences.MaterialListPreference <code.name.monkey.retromusic.preferences.MaterialListPreference
android:defaultValue="0" android:defaultValue="0"
@ -45,12 +23,7 @@
android:summary="@string/pref_summary_home_banner" android:summary="@string/pref_summary_home_banner"
android:title="@string/pref_title_home_banner" /> android:title="@string/pref_title_home_banner" />
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
android:defaultValue="false"
android:key="extra_song_info"
android:layout="@layout/list_item_view_switch"
android:summary="@string/pref_summary_extra_song_info"
android:title="@string/pref_title_extra_song_info" />
</code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory> </code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory>

View file

@ -78,7 +78,7 @@ public final class TintHelper {
} }
@CheckResult @CheckResult
@Nullable @NonNull
public static Drawable createTintedDrawable(Context context, public static Drawable createTintedDrawable(Context context,
@DrawableRes int res, @ColorInt int color) { @DrawableRes int res, @ColorInt int color) {
Drawable drawable = ContextCompat.getDrawable(context, res); Drawable drawable = ContextCompat.getDrawable(context, res);
@ -87,7 +87,7 @@ public final class TintHelper {
// This returns a NEW Drawable because of the mutate() call. The mutate() call is necessary because Drawables with the same resource have shared states otherwise. // This returns a NEW Drawable because of the mutate() call. The mutate() call is necessary because Drawables with the same resource have shared states otherwise.
@CheckResult @CheckResult
@Nullable @NonNull
public static Drawable createTintedDrawable(@Nullable Drawable drawable, @ColorInt int color) { public static Drawable createTintedDrawable(@Nullable Drawable drawable, @ColorInt int color) {
if (drawable == null) { if (drawable == null) {
return null; return null;