home: expand appbar when selection starts
Expand the home AppBarLayout when a selection begins (Excluding initialization)
This commit is contained in:
parent
f3365fc40b
commit
c353ffd705
18 changed files with 111 additions and 37 deletions
|
@ -96,7 +96,11 @@ class AlbumDetailFragment :
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentDetailBinding) {
|
override fun onDestroyBinding(binding: FragmentDetailBinding) {
|
||||||
super.onDestroyBinding(binding)
|
super.onDestroyBinding(binding)
|
||||||
binding.detailToolbar.setOnMenuItemClickListener(null)
|
binding.detailToolbar.apply {
|
||||||
|
setNavigationOnClickListener(null)
|
||||||
|
setOnMenuItemClickListener(null)
|
||||||
|
}
|
||||||
|
|
||||||
binding.detailRecycler.adapter = null
|
binding.detailRecycler.adapter = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,11 @@ class ArtistDetailFragment :
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentDetailBinding) {
|
override fun onDestroyBinding(binding: FragmentDetailBinding) {
|
||||||
super.onDestroyBinding(binding)
|
super.onDestroyBinding(binding)
|
||||||
binding.detailToolbar.setOnMenuItemClickListener(null)
|
binding.detailToolbar.apply {
|
||||||
|
setNavigationOnClickListener(null)
|
||||||
|
setOnMenuItemClickListener(null)
|
||||||
|
}
|
||||||
|
|
||||||
binding.detailRecycler.adapter = null
|
binding.detailRecycler.adapter = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,11 @@ class GenreDetailFragment :
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentDetailBinding) {
|
override fun onDestroyBinding(binding: FragmentDetailBinding) {
|
||||||
super.onDestroyBinding(binding)
|
super.onDestroyBinding(binding)
|
||||||
binding.detailToolbar.setOnMenuItemClickListener(null)
|
binding.detailToolbar.apply {
|
||||||
|
setNavigationOnClickListener(null)
|
||||||
|
setOnMenuItemClickListener(null)
|
||||||
|
}
|
||||||
|
|
||||||
binding.detailRecycler.adapter = null
|
binding.detailRecycler.adapter = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import androidx.core.view.iterator
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
@ -58,7 +59,7 @@ import org.oxycblt.auxio.music.system.Indexer
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.MainNavigationAction
|
import org.oxycblt.auxio.ui.MainNavigationAction
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.ui.SelectionViewModel
|
import org.oxycblt.auxio.ui.selection.SelectionViewModel
|
||||||
import org.oxycblt.auxio.ui.fragment.ViewBindingFragment
|
import org.oxycblt.auxio.ui.fragment.ViewBindingFragment
|
||||||
import org.oxycblt.auxio.util.*
|
import org.oxycblt.auxio.util.*
|
||||||
|
|
||||||
|
@ -69,10 +70,11 @@ import org.oxycblt.auxio.util.*
|
||||||
*/
|
*/
|
||||||
class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuItemClickListener {
|
class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuItemClickListener {
|
||||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||||
private val navModel: NavigationViewModel by activityViewModels()
|
|
||||||
private val homeModel: HomeViewModel by androidActivityViewModels()
|
private val homeModel: HomeViewModel by androidActivityViewModels()
|
||||||
private val selectionModel: SelectionViewModel by activityViewModels()
|
|
||||||
private val musicModel: MusicViewModel by activityViewModels()
|
private val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
private val navModel: NavigationViewModel by activityViewModels()
|
||||||
|
// Makes no sense to share selections across screens
|
||||||
|
private val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
|
|
||||||
// lifecycleObject builds this in the creation step, so doing this is okay.
|
// lifecycleObject builds this in the creation step, so doing this is okay.
|
||||||
private val storagePermissionLauncher: ActivityResultLauncher<String> by lifecycleObject {
|
private val storagePermissionLauncher: ActivityResultLauncher<String> by lifecycleObject {
|
||||||
|
@ -237,15 +239,12 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
|
||||||
private fun updateCurrentTab(tab: MusicMode) {
|
private fun updateCurrentTab(tab: MusicMode) {
|
||||||
// Make sure that we update the scrolling view and allowed menu items whenever
|
// Make sure that we update the scrolling view and allowed menu items whenever
|
||||||
// the tab changes.
|
// the tab changes.
|
||||||
val binding = requireBinding()
|
|
||||||
when (tab) {
|
when (tab) {
|
||||||
MusicMode.SONGS -> {
|
MusicMode.SONGS -> {
|
||||||
updateSortMenu(tab) { id -> id != R.id.option_sort_count }
|
updateSortMenu(tab) { id -> id != R.id.option_sort_count }
|
||||||
binding.homeAppbar.liftOnScrollTargetViewId = R.id.home_song_list
|
|
||||||
}
|
}
|
||||||
MusicMode.ALBUMS -> {
|
MusicMode.ALBUMS -> {
|
||||||
updateSortMenu(tab) { id -> id != R.id.option_sort_album }
|
updateSortMenu(tab) { id -> id != R.id.option_sort_album }
|
||||||
binding.homeAppbar.liftOnScrollTargetViewId = R.id.home_album_list
|
|
||||||
}
|
}
|
||||||
MusicMode.ARTISTS -> {
|
MusicMode.ARTISTS -> {
|
||||||
updateSortMenu(tab) { id ->
|
updateSortMenu(tab) { id ->
|
||||||
|
@ -254,7 +253,6 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
|
||||||
id == R.id.option_sort_count ||
|
id == R.id.option_sort_count ||
|
||||||
id == R.id.option_sort_duration
|
id == R.id.option_sort_duration
|
||||||
}
|
}
|
||||||
binding.homeAppbar.liftOnScrollTargetViewId = R.id.home_artist_list
|
|
||||||
}
|
}
|
||||||
MusicMode.GENRES -> {
|
MusicMode.GENRES -> {
|
||||||
updateSortMenu(tab) { id ->
|
updateSortMenu(tab) { id ->
|
||||||
|
@ -263,9 +261,10 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
|
||||||
id == R.id.option_sort_count ||
|
id == R.id.option_sort_count ||
|
||||||
id == R.id.option_sort_duration
|
id == R.id.option_sort_duration
|
||||||
}
|
}
|
||||||
binding.homeAppbar.liftOnScrollTargetViewId = R.id.home_genre_list
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requireBinding().homeAppbar.liftOnScrollTargetViewId = getRecyclerId(tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSortMenu(mode: MusicMode, isVisible: (Int) -> Boolean) {
|
private fun updateSortMenu(mode: MusicMode, isVisible: (Int) -> Boolean) {
|
||||||
|
@ -402,7 +401,15 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSelection(selected: List<Music>) {
|
private fun updateSelection(selected: List<Music>) {
|
||||||
requireBinding().homeToolbarOverlay.updateSelectionAmount(selected.size)
|
val binding = requireBinding()
|
||||||
|
if (binding.homeToolbarOverlay.updateSelectionAmount(selected.size) && selected.isNotEmpty()) {
|
||||||
|
logD("Significant selection occurred, expanding AppBar")
|
||||||
|
// Significant enough change where we want to expand the RecyclerView
|
||||||
|
binding.homeAppbar.expandWithRecycler(
|
||||||
|
binding.homePager.findViewById(
|
||||||
|
getRecyclerId(homeModel.currentTab.value))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleNavigation(item: Music?) {
|
private fun handleNavigation(item: Music?) {
|
||||||
|
@ -449,6 +456,14 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
|
||||||
adapter = HomePagerAdapter()
|
adapter = HomePagerAdapter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getRecyclerId(tab: MusicMode) =
|
||||||
|
when (tab) {
|
||||||
|
MusicMode.SONGS -> R.id.home_song_recycler
|
||||||
|
MusicMode.ALBUMS -> R.id.home_album_recycler
|
||||||
|
MusicMode.ARTISTS -> R.id.home_artist_recycler
|
||||||
|
MusicMode.GENRES -> R.id.home_genre_recycler
|
||||||
|
}
|
||||||
|
|
||||||
private inner class HomePagerAdapter :
|
private inner class HomePagerAdapter :
|
||||||
FragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle) {
|
FragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle) {
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ class AlbumListFragment : HomeListFragment<Album>() {
|
||||||
super.onBindingCreated(binding, savedInstanceState)
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
binding.homeRecycler.apply {
|
binding.homeRecycler.apply {
|
||||||
id = R.id.home_album_list
|
id = R.id.home_album_recycler
|
||||||
adapter = homeAdapter
|
adapter = homeAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ class ArtistListFragment : HomeListFragment<Artist>() {
|
||||||
super.onBindingCreated(binding, savedInstanceState)
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
binding.homeRecycler.apply {
|
binding.homeRecycler.apply {
|
||||||
id = R.id.home_artist_list
|
id = R.id.home_artist_recycler
|
||||||
adapter = homeAdapter
|
adapter = homeAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class GenreListFragment : HomeListFragment<Genre>() {
|
||||||
super.onBindingCreated(binding, savedInstanceState)
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
binding.homeRecycler.apply {
|
binding.homeRecycler.apply {
|
||||||
id = R.id.home_genre_list
|
id = R.id.home_genre_recycler
|
||||||
adapter = homeAdapter
|
adapter = homeAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ import androidx.fragment.app.activityViewModels
|
||||||
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
|
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
|
||||||
import org.oxycblt.auxio.home.HomeViewModel
|
import org.oxycblt.auxio.home.HomeViewModel
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.ui.SelectionViewModel
|
import org.oxycblt.auxio.ui.selection.SelectionViewModel
|
||||||
import org.oxycblt.auxio.ui.fastscroll.FastScrollRecyclerView
|
import org.oxycblt.auxio.ui.fastscroll.FastScrollRecyclerView
|
||||||
import org.oxycblt.auxio.ui.fragment.MenuFragment
|
import org.oxycblt.auxio.ui.fragment.MenuFragment
|
||||||
import org.oxycblt.auxio.ui.recycler.Item
|
import org.oxycblt.auxio.ui.recycler.Item
|
||||||
|
|
|
@ -54,7 +54,7 @@ class SongListFragment : HomeListFragment<Song>() {
|
||||||
super.onBindingCreated(binding, savedInstanceState)
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
binding.homeRecycler.apply {
|
binding.homeRecycler.apply {
|
||||||
id = R.id.home_song_list
|
id = R.id.home_song_recycler
|
||||||
adapter = homeAdapter
|
adapter = homeAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,9 @@ class PlaybackStateManager private constructor() {
|
||||||
private set
|
private set
|
||||||
private var _queue = mutableListOf<Song>()
|
private var _queue = mutableListOf<Song>()
|
||||||
|
|
||||||
|
private val orderedQueue = listOf<Song>()
|
||||||
|
private val shuffledQueue = listOf<Song>()
|
||||||
|
|
||||||
/** The current queue determined by [parent] */
|
/** The current queue determined by [parent] */
|
||||||
val queue
|
val queue
|
||||||
get() = _queue
|
get() = _queue
|
||||||
|
|
|
@ -22,15 +22,18 @@ import android.util.AttributeSet
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
|
import android.view.animation.AnimationUtils
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import org.oxycblt.auxio.util.coordinatorLayoutBehavior
|
import org.oxycblt.auxio.util.coordinatorLayoutBehavior
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An [AppBarLayout] that fixes a bug with the default implementation where the lifted state will
|
* An [AppBarLayout] that fixes several bugs with the default implementation where the lifted
|
||||||
* not properly respond to RecyclerView events.
|
* state will not properly respond to RecyclerView events.
|
||||||
*
|
*
|
||||||
* **Note:** This layout relies on [AppBarLayout.liftOnScrollTargetViewId] to figure out what
|
* **Note:** This layout relies on [AppBarLayout.liftOnScrollTargetViewId] to figure out what
|
||||||
* scrolling view to use. Failure to specify this will result in the layout not working.
|
* scrolling view to use. Failure to specify this will result in the layout not working.
|
||||||
|
@ -60,6 +63,17 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
viewTreeObserver.addOnPreDrawListener(onPreDraw)
|
viewTreeObserver.addOnPreDrawListener(onPreDraw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand this app bar layout with the given recyclerview, preventing it from
|
||||||
|
* jumping around.
|
||||||
|
*/
|
||||||
|
fun expandWithRecycler(recycler: RecyclerView?) {
|
||||||
|
setExpanded(true)
|
||||||
|
recycler?.let {
|
||||||
|
addOnOffsetChangedListener(ExpansionHackListener(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDetachedFromWindow() {
|
override fun onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow()
|
super.onDetachedFromWindow()
|
||||||
viewTreeObserver.removeOnPreDrawListener(onPreDraw)
|
viewTreeObserver.removeOnPreDrawListener(onPreDraw)
|
||||||
|
@ -88,4 +102,30 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
|
|
||||||
return scrollingChild
|
return scrollingChild
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack to prevent RecyclerView jumping when the appbar expands.
|
||||||
|
* Adapted from Material Files:
|
||||||
|
* https://github.com/zhanghai/MaterialFiles/blob/master/app/src/main/java/me/zhanghai/android/files/ui/AppBarLayoutExpandHackListener.kt
|
||||||
|
*/
|
||||||
|
private class ExpansionHackListener(private val recycler: RecyclerView) : OnOffsetChangedListener {
|
||||||
|
private val offsetAnimationMaxEndTime = (AnimationUtils.currentAnimationTimeMillis()
|
||||||
|
+ 600)
|
||||||
|
|
||||||
|
private var lastVerticalOffset: Int? = null
|
||||||
|
|
||||||
|
override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) {
|
||||||
|
if (verticalOffset == 0
|
||||||
|
|| AnimationUtils.currentAnimationTimeMillis() > offsetAnimationMaxEndTime) {
|
||||||
|
// AppBarLayout crashes with IndexOutOfBoundsException when a non-last listener removes
|
||||||
|
// itself, so we have to do the removal asynchronously.
|
||||||
|
appBarLayout.postOnAnimation { appBarLayout.removeOnOffsetChangedListener(this) }
|
||||||
|
}
|
||||||
|
val lastVerticalOffset = lastVerticalOffset
|
||||||
|
this.lastVerticalOffset = verticalOffset
|
||||||
|
if (lastVerticalOffset != null) {
|
||||||
|
recycler.scrollBy(0, verticalOffset - lastVerticalOffset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -463,7 +463,6 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun animateViewIn(view: View) {
|
private fun animateViewIn(view: View) {
|
||||||
logD(view.translationX)
|
|
||||||
view
|
view
|
||||||
.animate()
|
.animate()
|
||||||
.alpha(1f)
|
.alpha(1f)
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
package org.oxycblt.auxio.ui
|
package org.oxycblt.auxio.ui.selection
|
||||||
|
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.view.isInvisible
|
import androidx.core.view.isInvisible
|
||||||
import androidx.transition.TransitionManager
|
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
import com.google.android.material.transition.MaterialFadeThrough
|
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import kotlin.math.max
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around a Toolbar that enables an overlaid toolbar showing information about
|
* A wrapper around a Toolbar that enables an overlaid toolbar showing information about
|
||||||
|
@ -31,8 +26,6 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
setNavigationIcon(R.drawable.ic_close_24)
|
setNavigationIcon(R.drawable.ic_close_24)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val selectionMenu = selectionToolbar.menu
|
|
||||||
|
|
||||||
private var fadeThroughAnimator: ValueAnimator? = null
|
private var fadeThroughAnimator: ValueAnimator? = null
|
||||||
|
|
||||||
override fun onFinishInflate() {
|
override fun onFinishInflate() {
|
||||||
|
@ -103,8 +96,10 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isLaidOut) {
|
if (!isLaidOut) {
|
||||||
|
// Not laid out, just change it immediately while are not shown to the user.
|
||||||
|
// This is an initialization, so we return false despite changing.
|
||||||
changeToolbarAlpha(targetInnerAlpha)
|
changeToolbarAlpha(targetInnerAlpha)
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fadeThroughAnimator != null) {
|
if (fadeThroughAnimator != null) {
|
|
@ -15,7 +15,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.ui
|
package org.oxycblt.auxio.ui.selection
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
@ -23,6 +23,10 @@ import kotlinx.coroutines.flow.StateFlow
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ViewModel that manages the current selection.
|
||||||
|
* @author OxygenCobalt
|
||||||
|
*/
|
||||||
class SelectionViewModel : ViewModel() {
|
class SelectionViewModel : ViewModel() {
|
||||||
private val _selected = MutableStateFlow(listOf<Music>())
|
private val _selected = MutableStateFlow(listOf<Music>())
|
||||||
val selected: StateFlow<List<Music>>
|
val selected: StateFlow<List<Music>>
|
||||||
|
@ -47,4 +51,9 @@ class SelectionViewModel : ViewModel() {
|
||||||
_selected.value = listOf()
|
_selected.value = listOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
super.onCleared()
|
||||||
|
logD("Cleared")
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
style="@style/Widget.Auxio.AppBarLayout"
|
style="@style/Widget.Auxio.AppBarLayout"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<org.oxycblt.auxio.ui.SelectionToolbarOverlay
|
<org.oxycblt.auxio.ui.selection.SelectionToolbarOverlay
|
||||||
android:id="@+id/home_toolbar_overlay"
|
android:id="@+id/home_toolbar_overlay"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
app:menu="@menu/menu_home"
|
app:menu="@menu/menu_home"
|
||||||
app:title="@string/info_app_name" />
|
app:title="@string/info_app_name" />
|
||||||
|
|
||||||
</org.oxycblt.auxio.ui.SelectionToolbarOverlay>
|
</org.oxycblt.auxio.ui.selection.SelectionToolbarOverlay>
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
android:id="@+id/home_tabs"
|
android:id="@+id/home_tabs"
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_play_next_selection"
|
android:id="@+id/action_play_next_selection"
|
||||||
android:title="@string/lbl_play_next"
|
android:title="@string/lbl_play_next"
|
||||||
android:icon="@drawable/ic_play_next_24"
|
android:icon="@drawable/ic_play_next"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_queue_add_selection"
|
android:id="@+id/action_queue_add_selection"
|
||||||
|
android:icon="@drawable/ic_play_next"
|
||||||
android:title="@string/lbl_queue_add"
|
android:title="@string/lbl_queue_add"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
<!-- TOOD: Disabled until able to get queue system into shape -->
|
<!-- TOOD: Disabled until able to get queue system into shape -->
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<!-- This is for HomeFragment's AppBarLayout. Explanations for these can be found there. -->
|
<!-- This is for HomeFragment's AppBarLayout. Explanations for these can be found there. -->
|
||||||
<item name="home_song_list" type="id" />
|
<item name="home_song_recycler" type="id" />
|
||||||
<item name="home_album_list" type="id" />
|
<item name="home_album_recycler" type="id" />
|
||||||
<item name="home_artist_list" type="id" />
|
<item name="home_artist_recycler" type="id" />
|
||||||
<item name="home_genre_list" type="id" />
|
<item name="home_genre_recycler" type="id" />
|
||||||
|
|
||||||
<integer name="anim_fade_enter_duration">200</integer>
|
<integer name="anim_fade_enter_duration">200</integer>
|
||||||
<integer name="anim_fade_exit_duration">100</integer>
|
<integer name="anim_fade_exit_duration">100</integer>
|
||||||
|
|
Loading…
Reference in a new issue