settings: make tab dialog use checkboxes

Make the tab selection dialog use checkboxes instead of icons to make
it more user-friendly.
This commit is contained in:
OxygenCobalt 2021-10-20 19:37:20 -06:00
parent aa649ebf22
commit e01816a1dc
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
9 changed files with 41 additions and 55 deletions

View file

@ -194,14 +194,7 @@ class HomeFragment : Fragment() {
} }
TabLayoutMediator(binding.homeTabs, binding.homePager) { tab, pos -> TabLayoutMediator(binding.homeTabs, binding.homePager) { tab, pos ->
val labelRes = when (homeModel.tabs[pos]) { tab.setText(homeModel.tabs[pos].string)
DisplayMode.SHOW_SONGS -> R.string.lbl_songs
DisplayMode.SHOW_ALBUMS -> R.string.lbl_albums
DisplayMode.SHOW_ARTISTS -> R.string.lbl_artists
DisplayMode.SHOW_GENRES -> R.string.lbl_genres
}
tab.setText(labelRes)
}.attach() }.attach()
// --- VIEWMODEL SETUP --- // --- VIEWMODEL SETUP ---
@ -219,7 +212,7 @@ class HomeFragment : Fragment() {
homeModel.curTab.observe(viewLifecycleOwner) { tab -> homeModel.curTab.observe(viewLifecycleOwner) { tab ->
// Make sure that we update the scrolling view and allowed menu items before whenever // Make sure that we update the scrolling view and allowed menu items before whenever
// the tab changes. // the tab changes.
binding.homeAppbar.liftOnScrollTargetViewId = when (requireNotNull(tab)) { val targetView = when (requireNotNull(tab)) {
DisplayMode.SHOW_SONGS -> { DisplayMode.SHOW_SONGS -> {
updateSortMenu(sortItem, tab) updateSortMenu(sortItem, tab)
R.id.home_song_list R.id.home_song_list
@ -246,6 +239,8 @@ class HomeFragment : Fragment() {
R.id.home_genre_list R.id.home_genre_list
} }
} }
binding.homeAppbar.liftOnScrollTargetViewId = targetView
} }
detailModel.navToItem.observe(viewLifecycleOwner) { item -> detailModel.navToItem.observe(viewLifecycleOwner) { item ->

View file

@ -119,6 +119,12 @@ class SongListFragment : HomeListFragment() {
} }
} }
/**
* The viewholder for the play/shuffle header on the song header.
* Using a FAB would have been more conventional here, but it's so difficult to get a FAB
* to play along with edge-to-edge and nested RecyclerView instances to the point where I
* may as well not bother.
*/
private inner class PlayViewHolder( private inner class PlayViewHolder(
binding: ItemPlayShuffleBinding binding: ItemPlayShuffleBinding
) : RecyclerView.ViewHolder(binding.root) { ) : RecyclerView.ViewHolder(binding.root) {

View file

@ -87,10 +87,7 @@ class PlaybackFragment : Fragment() {
// Make marquee of song title work // Make marquee of song title work
binding.playbackSong.isSelected = true binding.playbackSong.isSelected = true
binding.playbackSeekBar.onConfirmListener = playbackModel::setPosition
binding.playbackSeekBar.onConfirmListener = { pos ->
playbackModel.setPosition(pos)
}
// --- VIEWMODEL SETUP -- // --- VIEWMODEL SETUP --

View file

@ -60,20 +60,14 @@ class TabAdapter(
// A. We don't have a real ViewModel state since this is a dialog // A. We don't have a real ViewModel state since this is a dialog
// B. Doing so would cause a relayout and the ripple effect to disappear // B. Doing so would cause a relayout and the ripple effect to disappear
// Instead, simply notify a tab change and let TabCustomizeDialog handle it. // Instead, simply notify a tab change and let TabCustomizeDialog handle it.
binding.tabIcon.isEnabled = !binding.tabIcon.isEnabled binding.tabIcon.isChecked = !binding.tabIcon.isChecked
binding.tabName.isEnabled = !binding.tabName.isEnabled
onTabSwitch(tab) onTabSwitch(tab)
} }
} }
binding.tabIcon.apply {
setImageResource(tab.mode.icon)
contentDescription = context.getString(tab.mode.string)
isEnabled = tab is Tab.Visible
}
binding.tabName.apply { binding.tabIcon.apply {
setText(tab.mode.string) setText(tab.mode.string)
isEnabled = tab is Tab.Visible isChecked = tab is Tab.Visible
} }
binding.tabDragHandle.setOnTouchListener { _, motionEvent -> binding.tabDragHandle.setOnTouchListener { _, motionEvent ->

View file

@ -18,7 +18,6 @@
package org.oxycblt.auxio.ui package org.oxycblt.auxio.ui
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
@ -28,11 +27,11 @@ import org.oxycblt.auxio.R
* changing them would also change the meaning. * changing them would also change the meaning.
* @author OxygenCobalt * @author OxygenCobalt
*/ */
enum class DisplayMode(@DrawableRes val icon: Int, @StringRes val string: Int) { enum class DisplayMode(@StringRes val string: Int) {
SHOW_SONGS(R.drawable.ic_song, R.string.lbl_songs), SHOW_SONGS(R.string.lbl_songs),
SHOW_ALBUMS(R.drawable.ic_album, R.string.lbl_albums), SHOW_ALBUMS(R.string.lbl_albums),
SHOW_ARTISTS(R.drawable.ic_artist, R.string.lbl_artists), SHOW_ARTISTS(R.string.lbl_artists),
SHOW_GENRES(R.drawable.ic_genre, R.string.lbl_genres); SHOW_GENRES(R.string.lbl_genres);
companion object { companion object {
private const val CONST_NULL = 0xA107 private const val CONST_NULL = 0xA107

View file

@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android" <ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/mtrl_btn_ripple_color"> android:color="@color/mtrl_btn_ripple_color">
<item> <item android:id="@android:id/background">
<shape android:shape="rectangle" <shape
android:shape="rectangle"
android:tint="@color/sel_accented"> android:tint="@color/sel_accented">
<corners android:radius="@dimen/spacing_mid_large" /> <corners android:radius="@dimen/spacing_large" />
<solid android:color="@android:color/white" /> <solid android:color="@android:color/white" />
</shape> </shape>
</item> </item>

View file

@ -9,8 +9,8 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:overScrollMode="never" android:overScrollMode="never"
android:paddingTop="@dimen/spacing_medium" android:paddingTop="@dimen/spacing_medium"
android:paddingStart="@dimen/spacing_small" android:paddingStart="@dimen/spacing_medium"
android:paddingEnd="@dimen/spacing_small" android:paddingEnd="@dimen/spacing_medium"
app:layoutManager="org.oxycblt.auxio.accent.AutoGridLayoutManager" app:layoutManager="org.oxycblt.auxio.accent.AutoGridLayoutManager"
app:layout_constraintBottom_toTopOf="@+id/accent_cancel" app:layout_constraintBottom_toTopOf="@+id/accent_cancel"
app:layout_constraintTop_toBottomOf="@+id/accent_header" app:layout_constraintTop_toBottomOf="@+id/accent_header"

View file

@ -7,7 +7,8 @@
android:theme="@style/ThemeOverlay.Accent" android:theme="@style/ThemeOverlay.Accent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="@dimen/spacing_small"> android:paddingTop="@dimen/spacing_small"
android:paddingBottom="@dimen/spacing_small">
<ImageButton <ImageButton
android:id="@+id/accent" android:id="@+id/accent"

View file

@ -9,31 +9,24 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:padding="0dp"> android:padding="0dp">
<ImageView <com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/tab_icon" android:id="@+id/tab_icon"
android:scaleType="fitCenter" android:layout_width="0dp"
android:padding="@dimen/spacing_small" style="@style/Widget.Material3.CompoundButton.CheckBox"
android:layout_width="@dimen/size_btn_small" android:layout_height="wrap_content"
android:layout_height="@dimen/size_btn_small" android:layout_marginStart="@dimen/spacing_medium"
android:layout_margin="@dimen/spacing_small" android:layout_marginTop="@dimen/spacing_small"
android:src="@drawable/ic_artist" android:layout_marginBottom="@dimen/spacing_small"
app:tint="@color/sel_accented" android:clickable="false"
android:focusable="false"
android:textSize="@dimen/text_size_small"
android:paddingStart="@dimen/spacing_medium"
app:buttonCompat="@null"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tab_drag_handle"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:ignore="contentDescription" /> tools:ignore="RtlSymmetry,contentDescription"
<TextView
android:id="@+id/tab_name"
style="@style/Widget.Auxio.TextView.Item.Primary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_medium"
android:gravity="center"
android:maxLines="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/tab_icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="Artist" /> tools:text="Artist" />
<ImageView <ImageView