diff --git a/.gitignore b/.gitignore index 5f1da0430..aa3f9683b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,3 @@ captures/ .externalNativeBuild *.iml .cxx - -# Patched material -app/src/main/com/google/android/material diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a4f2c73f..72b9f003c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ at the cost of longer loading times - Added support for date tags, including more fine-grained dates [#159, dependent on this feature] - Added support for release types signifying EPs, Singles, Compilations, and more [#158, dependent on this feature] - Added basic awareness of multi-value vorbis tags [#197, dependent on this feature] +- Completely reworked the main playback UI + - Queue can now be swiped up [#92] + - Playing song is now shown in queue [#92] + - Added ability to play songs from queue [#92] - Added Last Added sorting - Search now takes sort tags and file names in account [#184] - Added option to clear playback state in settings diff --git a/app/src/main/java/com/google/android/material/bottomsheet/NeoBottomSheetBehavior.java b/app/src/main/java/com/google/android/material/bottomsheet/NeoBottomSheetBehavior.java index 471f4bad7..9d5fdffd6 100644 --- a/app/src/main/java/com/google/android/material/bottomsheet/NeoBottomSheetBehavior.java +++ b/app/src/main/java/com/google/android/material/bottomsheet/NeoBottomSheetBehavior.java @@ -739,95 +739,83 @@ public class NeoBottomSheetBehavior extends CoordinatorLayout.Be nestedScrolled = true; } - -@Override -public void onStopNestedScroll( - @NonNull CoordinatorLayout coordinatorLayout, - @NonNull V child, - @NonNull View target, - int type) { - if (child.getTop() == getExpandedOffset()) { - setStateInternal(STATE_EXPANDED); - return; - } - if (isNestedScrollingCheckEnabled() - && (nestedScrollingChildRef == null - || target != nestedScrollingChildRef.get() - || !nestedScrolled)) { - return; - } - @StableState int targetState; - if (lastNestedScrollDy > 0) { - if (fitToContents) { - targetState = STATE_EXPANDED; - } else { - // MODIFICATION: Make nested scrolling respond to shouldSkipHalfExpandedStateWhenDragging - int currentTop = child.getTop(); - if (currentTop < halfExpandedOffset) { - targetState = STATE_EXPANDED; - } else { - if (shouldSkipHalfExpandedStateWhenDragging()) { - targetState = STATE_COLLAPSED; - } else { - targetState = STATE_HALF_EXPANDED; - } - } + @Override + public void onStopNestedScroll( + @NonNull CoordinatorLayout coordinatorLayout, + @NonNull V child, + @NonNull View target, + int type) { + if (child.getTop() == getExpandedOffset()) { + setStateInternal(STATE_EXPANDED); + return; } - } else if (hideable && shouldHide(child, getYVelocity())) { - targetState = STATE_HIDDEN; - } else if (lastNestedScrollDy == 0) { - int currentTop = child.getTop(); - if (fitToContents) { - if (Math.abs(currentTop - fitToContentsOffset) < Math.abs(currentTop - collapsedOffset)) { + if (isNestedScrollingCheckEnabled() + && (nestedScrollingChildRef == null + || target != nestedScrollingChildRef.get() + || !nestedScrolled)) { + return; + } + @StableState int targetState; + if (lastNestedScrollDy > 0) { + if (fitToContents) { targetState = STATE_EXPANDED; } else { - targetState = STATE_COLLAPSED; - } - } else { - if (currentTop < halfExpandedOffset) { - if (currentTop < Math.abs(currentTop - collapsedOffset)) { + int currentTop = child.getTop(); + if (currentTop < halfExpandedOffset) { targetState = STATE_EXPANDED; } else { if (shouldSkipHalfExpandedStateWhenDragging()) { - targetState = STATE_COLLAPSED; + targetState = STATE_EXPANDED; } else { targetState = STATE_HALF_EXPANDED; } } - } else { - // MODIFICATION: Make nested scrolling respond to shouldSkipHalfExpandedStateWhenDragging - if (shouldSkipHalfExpandedStateWhenDragging()) { - targetState = STATE_COLLAPSED; - } else { - if (Math.abs(currentTop - halfExpandedOffset) < Math.abs(currentTop - collapsedOffset)) { - targetState = STATE_HALF_EXPANDED; - } else { - targetState = STATE_COLLAPSED; - } - } } - } - } else { - if (fitToContents) { - targetState = STATE_COLLAPSED; - } else { - // Settle to nearest height. - // MODIFICATION: Make nested scrolling respond to shouldSkipHalfExpandedStateWhenDragging + } else if (hideable && shouldHide(child, getYVelocity())) { + targetState = STATE_HIDDEN; + } else if (lastNestedScrollDy == 0) { int currentTop = child.getTop(); - if (shouldSkipHalfExpandedStateWhenDragging()) { + if (fitToContents) { + if (Math.abs(currentTop - fitToContentsOffset) < Math.abs(currentTop - collapsedOffset)) { + targetState = STATE_EXPANDED; + } else { + targetState = STATE_COLLAPSED; + } + } else { + if (currentTop < halfExpandedOffset) { + if (currentTop < Math.abs(currentTop - collapsedOffset)) { + targetState = STATE_EXPANDED; + } else { + if (shouldSkipHalfExpandedStateWhenDragging()) { + targetState = STATE_COLLAPSED; + } else { + targetState = STATE_HALF_EXPANDED; + } + } + } else { + if (shouldSkipHalfExpandedStateWhenDragging() || Math.abs(currentTop - halfExpandedOffset) >= Math.abs(currentTop - collapsedOffset)) { + targetState = STATE_COLLAPSED; + } else { + targetState = STATE_HALF_EXPANDED; + } + } + } + } else { + if (fitToContents) { targetState = STATE_COLLAPSED; } else { - if (Math.abs(currentTop - halfExpandedOffset) < Math.abs(currentTop - collapsedOffset)) { - targetState = STATE_HALF_EXPANDED; - } else { + // Settle to nearest height. + int currentTop = child.getTop(); + if (shouldSkipHalfExpandedStateWhenDragging() || Math.abs(currentTop - halfExpandedOffset) >= Math.abs(currentTop - collapsedOffset)) { targetState = STATE_COLLAPSED; + } else { + targetState = STATE_HALF_EXPANDED; } } } + startSettling(child, targetState, false); + nestedScrolled = false; } - startSettling(child, targetState, false); - nestedScrolled = false; -} @Override public void onNestedScroll( diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index 97a7dba43..deb75c451 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -26,8 +26,10 @@ import androidx.core.view.isInvisible import androidx.fragment.app.activityViewModels import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController +import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.NeoBottomSheetBehavior import com.google.android.material.transition.MaterialFadeThrough +import java.util.* import kotlin.math.max import kotlin.math.min import org.oxycblt.auxio.databinding.FragmentMainBinding @@ -35,13 +37,11 @@ import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackSheetBehavior import org.oxycblt.auxio.playback.PlaybackViewModel +import org.oxycblt.auxio.playback.queue.QueueSheetBehavior import org.oxycblt.auxio.ui.MainNavigationAction import org.oxycblt.auxio.ui.NavigationViewModel import org.oxycblt.auxio.ui.fragment.ViewBindingFragment -import org.oxycblt.auxio.util.androidActivityViewModels -import org.oxycblt.auxio.util.collect -import org.oxycblt.auxio.util.collectImmediately -import org.oxycblt.auxio.util.coordinatorLayoutBehavior +import org.oxycblt.auxio.util.* /** * A wrapper around the home fragment that shows the playback fragment and controls the more @@ -85,7 +85,27 @@ class MainFragment : ViewBindingFragment() { override fun onStateChanged(bottomSheet: View, newState: Int) {} }) - binding.root.post { handleSheetTransitions() } + val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior + + queueSheetBehavior.addBottomSheetCallback( + object : NeoBottomSheetBehavior.BottomSheetCallback() { + override fun onSlide(bottomSheet: View, slideOffset: Float) { + handleSheetTransitions() + } + + override fun onStateChanged(bottomSheet: View, newState: Int) { + playbackSheetBehavior.isDraggable = + !playbackSheetBehavior.isHideable && + newState == BottomSheetBehavior.STATE_COLLAPSED + } + }) + + binding.root.post { + handleSheetTransitions() + playbackSheetBehavior.isDraggable = + !playbackSheetBehavior.isHideable && + queueSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED + } // --- VIEWMODEL SETUP --- @@ -109,8 +129,10 @@ class MainFragment : ViewBindingFragment() { val playbackSheetBehavior = binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior + val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior + val playbackRatio = max(playbackSheetBehavior.calculateSlideOffset(), 0f) - val queueRatio = 0f + val queueRatio = max(queueSheetBehavior.calculateSlideOffset(), 0f) val outRatio = 1 - playbackRatio val halfOutRatio = min(playbackRatio * 2, 1f) @@ -118,20 +140,26 @@ class MainFragment : ViewBindingFragment() { val halfOutQueueRatio = min(queueRatio * 2, 1f) val halfInQueueRatio = max(queueRatio - 0.5f, 0f) * 2 - playbackSheetBehavior.sheetBackgroundDrawable.alpha = (outRatio * 255).toInt() - binding.playbackSheet.translationZ = 3f * outRatio - binding.playbackPanelFragment.alpha = min(halfInPlaybackRatio, 1 - halfOutQueueRatio) - // binding.queueRecycler.alpha = max(queueOffset, 0f) - binding.exploreNavHost.apply { alpha = outRatio isInvisible = alpha == 0f } + binding.playbackSheet.translationZ = 3f * outRatio + playbackSheetBehavior.sheetBackgroundDrawable.alpha = (outRatio * 255).toInt() + binding.playbackBarFragment.apply { alpha = max(1 - halfOutRatio, halfInQueueRatio) - lastInsets?.let { translationY = it.systemWindowInsetTop * halfOutRatio } + isInvisible = alpha == 0f + lastInsets?.let { translationY = it.systemBarInsetsCompat.top * halfOutRatio } } + + binding.playbackPanelFragment.apply { + alpha = min(halfInPlaybackRatio, 1 - halfOutQueueRatio) + isInvisible = alpha == 0f + } + + binding.queueFragment.alpha = queueRatio } private fun handleMainNavigation(action: MainNavigationAction?) { @@ -139,16 +167,8 @@ class MainFragment : ViewBindingFragment() { val binding = requireBinding() when (action) { - is MainNavigationAction.Expand -> { - val playbackSheetBehavior = - binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior - playbackSheetBehavior.state = NeoBottomSheetBehavior.STATE_EXPANDED - } - is MainNavigationAction.Collapse -> { - val playbackSheetBehavior = - binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior - playbackSheetBehavior.state = NeoBottomSheetBehavior.STATE_COLLAPSED - } + is MainNavigationAction.Expand -> tryExpandAll() + is MainNavigationAction.Collapse -> tryCollapseAll() is MainNavigationAction.Settings -> findNavController().navigate(MainFragmentDirections.actionShowSettings()) is MainNavigationAction.About -> @@ -163,13 +183,7 @@ class MainFragment : ViewBindingFragment() { private fun handleExploreNavigation(item: Music?) { if (item != null) { - val binding = requireBinding() - val playbackSheetBehavior = - binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior - - if (playbackSheetBehavior.state == NeoBottomSheetBehavior.STATE_EXPANDED) { - playbackSheetBehavior.state = NeoBottomSheetBehavior.STATE_COLLAPSED - } + tryCollapseAll() } } @@ -193,11 +207,7 @@ class MainFragment : ViewBindingFragment() { inner class DynamicBackPressedCallback : OnBackPressedCallback(false) { override fun handleOnBackPressed() { val binding = requireBinding() - val playbackSheetBehavior = - binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior - if (playbackSheetBehavior.state == NeoBottomSheetBehavior.STATE_EXPANDED) { - playbackSheetBehavior.state = NeoBottomSheetBehavior.STATE_COLLAPSED - } else { + if (!tryCollapseAll()) { val navController = binding.exploreNavHost.findNavController() if (navController.currentDestination?.id == @@ -211,4 +221,38 @@ class MainFragment : ViewBindingFragment() { } } } + + private fun tryExpandAll(): Boolean { + val binding = requireBinding() + val playbackSheetBehavior = + binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior + + if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN && + playbackSheetBehavior.state != BottomSheetBehavior.STATE_EXPANDED) { + playbackSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED + return true + } + + return false + } + + private fun tryCollapseAll(): Boolean { + val binding = requireBinding() + val playbackSheetBehavior = + binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior + + if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN && + playbackSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED) { + playbackSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + + val queueSheetBehavior = + binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior + + queueSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + + return true + } + + return false + } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt index fb04f2c16..21aa19830 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt @@ -24,7 +24,6 @@ import androidx.appcompat.widget.Toolbar import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import kotlin.math.max import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding import org.oxycblt.auxio.music.MusicParent @@ -38,7 +37,6 @@ import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.getDrawableSafe import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.systemBarInsetsCompat -import org.oxycblt.auxio.util.systemGestureInsetsCompat import org.oxycblt.auxio.util.textSafe /** @@ -65,13 +63,8 @@ class PlaybackPanelFragment : // --- UI SETUP --- binding.root.setOnApplyWindowInsetsListener { view, insets -> - // The playback controls should be inset upwards at least a little bit more than usual, - // just for quality of life. While the old 3-button navigation does this for us, when - // bar navigation is used, we use the gesture padding to add that extra portion of - // space. val bars = insets.systemBarInsetsCompat - val gestures = insets.systemGestureInsetsCompat - view.updatePadding(top = bars.top, bottom = max(gestures.bottom, bars.bottom)) + view.updatePadding(top = bars.top, bottom = bars.bottom) insets } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt index 6cedefe30..686e2ceff 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt @@ -24,8 +24,11 @@ import android.view.View import android.view.ViewGroup import android.view.WindowInsets import androidx.coordinatorlayout.widget.CoordinatorLayout +import kotlin.math.max import org.oxycblt.auxio.ui.AuxioSheetBehavior import org.oxycblt.auxio.util.logD +import org.oxycblt.auxio.util.systemBarInsetsCompat +import org.oxycblt.auxio.util.systemGestureInsetsCompat class PlaybackSheetBehavior(context: Context, attributeSet: AttributeSet?) : AuxioSheetBehavior(context, attributeSet) { @@ -45,7 +48,9 @@ class PlaybackSheetBehavior(context: Context, attributeSet: AttributeS (child as ViewGroup).apply { setOnApplyWindowInsetsListener { v, insets -> lastInsets = insets - peekHeight = getChildAt(0).measuredHeight + insets.systemGestureInsets.bottom + val bars = insets.systemBarInsetsCompat + val gestures = insets.systemGestureInsetsCompat + peekHeight = getChildAt(0).measuredHeight + max(gestures.bottom, bars.bottom) insets } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt index cb6de1e66..6f261b688 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt @@ -19,6 +19,7 @@ package org.oxycblt.auxio.playback.queue import android.annotation.SuppressLint import android.content.Context +import android.graphics.drawable.LayerDrawable import android.view.MotionEvent import android.view.View import androidx.core.view.isInvisible @@ -54,10 +55,20 @@ private constructor( val backgroundDrawable = MaterialShapeDrawable.createWithElevationOverlay(binding.root.context).apply { fillColor = binding.context.getAttrColorSafe(R.attr.colorSurface).stateList + elevation = binding.context.getDimenSafe(R.dimen.elevation_normal) * 5 } init { - binding.body.background = backgroundDrawable + binding.body.background = + LayerDrawable( + arrayOf( + MaterialShapeDrawable.createWithElevationOverlay(binding.context).apply { + fillColor = binding.context.getAttrColorSafe(R.attr.colorSurface).stateList + elevation = binding.context.getDimenSafe(R.dimen.elevation_normal) + }, + backgroundDrawable)) + + backgroundDrawable.alpha = 0 } @SuppressLint("ClickableViewAccessibility") diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt index a1471f0be..7da9019c3 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt @@ -86,12 +86,15 @@ class QueueDragCallback(private val playbackModel: QueueViewModel) : ItemTouchHe logD("Lifting queue item") val bg = holder.backgroundDrawable - val elevation = recyclerView.context.getDimenSafe(R.dimen.elevation_small) + val elevation = recyclerView.context.getDimenSafe(R.dimen.elevation_normal) holder.itemView .animate() .translationZ(elevation) .setDuration(100) - .setUpdateListener { bg.elevation = holder.itemView.translationZ } + .setUpdateListener { + bg.alpha = ((holder.itemView.translationZ / elevation) * 255).toInt() + logD("in ${bg.alpha} ${holder.itemView.translationZ}") + } .setInterpolator(AccelerateDecelerateInterpolator()) .start() @@ -124,11 +127,15 @@ class QueueDragCallback(private val playbackModel: QueueViewModel) : ItemTouchHe logD("Dropping queue item") val bg = holder.backgroundDrawable + val elevation = recyclerView.context.getDimenSafe(R.dimen.elevation_normal) holder.itemView .animate() - .translationZ(0.0f) + .translationZ(0f) .setDuration(100) - .setUpdateListener { bg.elevation = holder.itemView.translationZ } + .setUpdateListener { + bg.alpha = ((holder.itemView.translationZ / elevation) * 255).toInt() + logD("out ${bg.alpha} ${holder.itemView.translationZ} ${elevation}") + } .setInterpolator(AccelerateDecelerateInterpolator()) .start() } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt index 34612f674..a00b90bb2 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt @@ -21,7 +21,6 @@ import android.os.Bundle import android.view.LayoutInflater import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.databinding.FragmentQueueBinding @@ -42,8 +41,6 @@ class QueueFragment : ViewBindingFragment(), QueueItemList override fun onCreateBinding(inflater: LayoutInflater) = FragmentQueueBinding.inflate(inflater) override fun onBindingCreated(binding: FragmentQueueBinding, savedInstanceState: Bundle?) { - binding.queueToolbar.setNavigationOnClickListener { findNavController().navigateUp() } - binding.queueRecycler.apply { adapter = queueAdapter touchHelper.attachToRecyclerView(this) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueSheetBehavior.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueSheetBehavior.kt new file mode 100644 index 000000000..5235171d4 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueSheetBehavior.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Auxio Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.oxycblt.auxio.playback.queue + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.view.ViewGroup +import androidx.coordinatorlayout.widget.CoordinatorLayout +import kotlin.math.max +import org.oxycblt.auxio.R +import org.oxycblt.auxio.ui.AuxioSheetBehavior +import org.oxycblt.auxio.util.* + +class QueueSheetBehavior(context: Context, attributeSet: AttributeSet?) : + AuxioSheetBehavior(context, attributeSet) { + private var barHeight = 0 + private var barSpacing = context.getDimenSizeSafe(R.dimen.spacing_small) + + init { + sheetBackgroundDrawable.setCornerSize(context.getDimenSafe(R.dimen.size_corners_medium)) + } + + override fun layoutDependsOn(parent: CoordinatorLayout, child: V, dependency: View) = + dependency.id == R.id.playback_bar_fragment + + override fun onDependentViewChanged( + parent: CoordinatorLayout, + child: V, + dependency: View + ): Boolean { + val ok = super.onDependentViewChanged(parent, child, dependency) + barHeight = dependency.height + return ok + } + + override fun onLayoutChild(parent: CoordinatorLayout, child: V, layoutDirection: Int): Boolean { + val success = super.onLayoutChild(parent, child, layoutDirection) + + child.setOnApplyWindowInsetsListener { _, insets -> + val bars = insets.systemBarInsetsCompat + val gestures = insets.systemGestureInsetsCompat + + expandedOffset = bars.top + barHeight + barSpacing + peekHeight = + (child as ViewGroup).getChildAt(0).height + max(gestures.bottom, bars.bottom) + insets.replaceSystemBarInsetsCompat( + bars.left, bars.top, bars.right, expandedOffset + bars.bottom) + } + + return success + } +} diff --git a/app/src/main/java/org/oxycblt/auxio/ui/AuxioSheetBehavior.kt b/app/src/main/java/org/oxycblt/auxio/ui/AuxioSheetBehavior.kt index f54d241a7..a24023413 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/AuxioSheetBehavior.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/AuxioSheetBehavior.kt @@ -35,7 +35,7 @@ abstract class AuxioSheetBehavior(context: Context, attributeSet: Attr val sheetBackgroundDrawable = MaterialShapeDrawable.createWithElevationOverlay(context).apply { fillColor = context.getAttrColorSafe(R.attr.colorSurface).stateList - elevation = context.pxOfDp(elevationNormal).toFloat() + elevation = elevationNormal } init { diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index a5c1436cf..6b631d333 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -16,7 +16,7 @@ app:navGraph="@navigation/nav_explore" tools:layout="@layout/fragment_home" /> - + android:layout_height="match_parent" + app:layout_behavior="org.oxycblt.auxio.ui.BottomSheetContentViewBehavior" /> - + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_queue.xml b/app/src/main/res/layout/fragment_queue.xml index 06a4533ab..14a62f299 100644 --- a/app/src/main/res/layout/fragment_queue.xml +++ b/app/src/main/res/layout/fragment_queue.xml @@ -1,34 +1,12 @@ - - - - - - - - - - - \ No newline at end of file + android:overScrollMode="ifContentScrolls" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" + tools:listitem="@layout/item_queue_song" />