ui: misc bottom sheet changes

Tweak parts of the bottom sheet system for UI consistency.
This commit is contained in:
OxygenCobalt 2022-07-30 09:15:38 -06:00
parent ed2f836280
commit 7467d89a45
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
9 changed files with 39 additions and 33 deletions

View file

@ -506,8 +506,6 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
} }
if (viewRef == null) { if (viewRef == null) {
Log.d("NeoBottomSheetBehavior", "Lay out time");
// First layout with this behavior. // First layout with this behavior.
peekHeightMin = peekHeightMin =
parent.getResources().getDimensionPixelSize(R.dimen.design_bottom_sheet_peek_height_min); parent.getResources().getDimensionPixelSize(R.dimen.design_bottom_sheet_peek_height_min);
@ -762,6 +760,7 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
if (fitToContents) { if (fitToContents) {
targetState = STATE_EXPANDED; targetState = STATE_EXPANDED;
} else { } else {
// MODIFICATION: Fix nested scrolling with skipping half-expanded state
int currentTop = child.getTop(); int currentTop = child.getTop();
if (currentTop < halfExpandedOffset) { if (currentTop < halfExpandedOffset) {
targetState = STATE_EXPANDED; targetState = STATE_EXPANDED;
@ -795,6 +794,7 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
} }
} }
} else { } else {
// MODIFICATION: Fix nested scrolling with skipping half-expanded state
if (shouldSkipHalfExpandedStateWhenDragging() || Math.abs(currentTop - halfExpandedOffset) >= Math.abs(currentTop - collapsedOffset)) { if (shouldSkipHalfExpandedStateWhenDragging() || Math.abs(currentTop - halfExpandedOffset) >= Math.abs(currentTop - collapsedOffset)) {
targetState = STATE_COLLAPSED; targetState = STATE_COLLAPSED;
} else { } else {
@ -806,6 +806,7 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
if (fitToContents) { if (fitToContents) {
targetState = STATE_COLLAPSED; targetState = STATE_COLLAPSED;
} else { } else {
// MODIFICATION: Fix nested scrolling with skipping half-expanded state
// Settle to nearest height. // Settle to nearest height.
int currentTop = child.getTop(); int currentTop = child.getTop();
if (shouldSkipHalfExpandedStateWhenDragging() || Math.abs(currentTop - halfExpandedOffset) >= Math.abs(currentTop - collapsedOffset)) { if (shouldSkipHalfExpandedStateWhenDragging() || Math.abs(currentTop - halfExpandedOffset) >= Math.abs(currentTop - collapsedOffset)) {
@ -1078,7 +1079,6 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
*/ */
public float calculateSlideOffset() { public float calculateSlideOffset() {
if (viewRef == null) { if (viewRef == null) {
Log.d("NeoBottomSheetBehavior", "No view ref");
return Float.MIN_VALUE; return Float.MIN_VALUE;
} }
@ -1087,8 +1087,6 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
return calculateSlideOffset(bottomSheet.getTop()); return calculateSlideOffset(bottomSheet.getTop());
} }
Log.d("NeoBottomSheetBehavior", "No bottom sheet");
return Float.MIN_VALUE; return Float.MIN_VALUE;
} }

View file

@ -28,7 +28,6 @@ import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialFadeThrough
import java.util.*
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import org.oxycblt.auxio.databinding.FragmentMainBinding import org.oxycblt.auxio.databinding.FragmentMainBinding
@ -160,7 +159,7 @@ class MainFragment :
binding.queueFragment.alpha = queueRatio binding.queueFragment.alpha = queueRatio
playbackSheetBehavior.isDraggable = playbackSheetBehavior.isDraggable =
!playbackSheetBehavior.isHideable && playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN &&
queueSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED queueSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED
} }
@ -227,7 +226,7 @@ class MainFragment :
val playbackSheetBehavior = val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
if (song != null) { if (song != null) {
playbackSheetBehavior.unsideSafe() playbackSheetBehavior.unhideSafe()
} else { } else {
playbackSheetBehavior.hideSafe() playbackSheetBehavior.hideSafe()
} }

View file

@ -26,7 +26,6 @@ import android.view.WindowInsets
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import kotlin.math.max import kotlin.math.max
import org.oxycblt.auxio.ui.AuxioSheetBehavior import org.oxycblt.auxio.ui.AuxioSheetBehavior
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.systemBarInsetsCompat import org.oxycblt.auxio.util.systemBarInsetsCompat
import org.oxycblt.auxio.util.systemGestureInsetsCompat import org.oxycblt.auxio.util.systemGestureInsetsCompat
@ -46,7 +45,7 @@ class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeS
val success = super.onLayoutChild(parent, child, layoutDirection) val success = super.onLayoutChild(parent, child, layoutDirection)
(child as ViewGroup).apply { (child as ViewGroup).apply {
setOnApplyWindowInsetsListener { v, insets -> setOnApplyWindowInsetsListener { _, insets ->
lastInsets = insets lastInsets = insets
val bars = insets.systemBarInsetsCompat val bars = insets.systemBarInsetsCompat
val gestures = insets.systemGestureInsetsCompat val gestures = insets.systemGestureInsetsCompat
@ -64,9 +63,8 @@ class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeS
state = STATE_HIDDEN state = STATE_HIDDEN
} }
fun unsideSafe() { fun unhideSafe() {
isHideable = false isHideable = false
isDraggable = true isDraggable = true
logD(state)
} }
} }

View file

@ -93,7 +93,6 @@ class QueueDragCallback(private val playbackModel: QueueViewModel) : ItemTouchHe
.setDuration(100) .setDuration(100)
.setUpdateListener { .setUpdateListener {
bg.alpha = ((holder.itemView.translationZ / elevation) * 255).toInt() bg.alpha = ((holder.itemView.translationZ / elevation) * 255).toInt()
logD("in ${bg.alpha} ${holder.itemView.translationZ}")
} }
.setInterpolator(AccelerateDecelerateInterpolator()) .setInterpolator(AccelerateDecelerateInterpolator())
.start() .start()
@ -134,7 +133,6 @@ class QueueDragCallback(private val playbackModel: QueueViewModel) : ItemTouchHe
.setDuration(100) .setDuration(100)
.setUpdateListener { .setUpdateListener {
bg.alpha = ((holder.itemView.translationZ / elevation) * 255).toInt() bg.alpha = ((holder.itemView.translationZ / elevation) * 255).toInt()
logD("out ${bg.alpha} ${holder.itemView.translationZ} ${elevation}")
} }
.setInterpolator(AccelerateDecelerateInterpolator()) .setInterpolator(AccelerateDecelerateInterpolator())
.start() .start()

View file

@ -24,10 +24,11 @@ import android.view.WindowInsets
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.bottomsheet.NeoBottomSheetBehavior import com.google.android.material.bottomsheet.NeoBottomSheetBehavior
import kotlin.math.abs import kotlin.math.abs
import org.oxycblt.auxio.util.coordinatorLayoutBehavior
import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat
import org.oxycblt.auxio.util.systemBarInsetsCompat import org.oxycblt.auxio.util.systemBarInsetsCompat
class BottomSheetContentViewBehavior<V : View>(context: Context, attributeSet: AttributeSet?) : class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: AttributeSet?) :
CoordinatorLayout.Behavior<V>(context, attributeSet) { CoordinatorLayout.Behavior<V>(context, attributeSet) {
private var lastInsets: WindowInsets? = null private var lastInsets: WindowInsets? = null
private var dep: View? = null private var dep: View? = null
@ -55,9 +56,7 @@ class BottomSheetContentViewBehavior<V : View>(context: Context, attributeSet: A
val dep = dep ?: return@setOnApplyWindowInsetsListener insets val dep = dep ?: return@setOnApplyWindowInsetsListener insets
val bars = insets.systemBarInsetsCompat val bars = insets.systemBarInsetsCompat
val behavior = val behavior = dep.coordinatorLayoutBehavior as NeoBottomSheetBehavior
(dep.layoutParams as CoordinatorLayout.LayoutParams).behavior
as NeoBottomSheetBehavior
val offset = behavior.calculateSlideOffset() val offset = behavior.calculateSlideOffset()
if (behavior.peekHeight < 0 || offset == Float.MIN_VALUE) { if (behavior.peekHeight < 0 || offset == Float.MIN_VALUE) {
@ -78,8 +77,7 @@ class BottomSheetContentViewBehavior<V : View>(context: Context, attributeSet: A
} }
private fun measureContent(parent: View, child: View, dep: View): Boolean { private fun measureContent(parent: View, child: View, dep: View): Boolean {
val behavior = val behavior = dep.coordinatorLayoutBehavior as NeoBottomSheetBehavior
(dep.layoutParams as CoordinatorLayout.LayoutParams).behavior as NeoBottomSheetBehavior
val offset = behavior.calculateSlideOffset() val offset = behavior.calculateSlideOffset()
if (behavior.peekHeight < 0 || offset == Float.MIN_VALUE) { if (behavior.peekHeight < 0 || offset == Float.MIN_VALUE) {
@ -107,8 +105,7 @@ class BottomSheetContentViewBehavior<V : View>(context: Context, attributeSet: A
} }
override fun layoutDependsOn(parent: CoordinatorLayout, child: V, dependency: View): Boolean { override fun layoutDependsOn(parent: CoordinatorLayout, child: V, dependency: View): Boolean {
if ((dependency.layoutParams as CoordinatorLayout.LayoutParams).behavior if (dependency.coordinatorLayoutBehavior is NeoBottomSheetBehavior) {
is NeoBottomSheetBehavior) {
dep = dependency dep = dependency
return true return true
} }
@ -121,6 +118,11 @@ class BottomSheetContentViewBehavior<V : View>(context: Context, attributeSet: A
child: V, child: V,
dependency: View dependency: View
): Boolean { ): Boolean {
val behavior = dependency.coordinatorLayoutBehavior as NeoBottomSheetBehavior
if (behavior.calculateSlideOffset() > 0) {
return false
}
lastInsets?.let(child::dispatchApplyWindowInsets) lastInsets?.let(child::dispatchApplyWindowInsets)
return measureContent(parent, child, dependency) && return measureContent(parent, child, dependency) &&
onLayoutChild(parent, child, parent.layoutDirection) onLayoutChild(parent, child, parent.layoutDirection)

View file

@ -12,7 +12,7 @@
android:name="androidx.navigation.fragment.NavHostFragment" android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="org.oxycblt.auxio.ui.BottomSheetContentViewBehavior" app:layout_behavior="org.oxycblt.auxio.ui.BottomSheetContentBehavior"
app:navGraph="@navigation/nav_explore" app:navGraph="@navigation/nav_explore"
tools:layout="@layout/fragment_home" /> tools:layout="@layout/fragment_home" />
@ -33,7 +33,7 @@
android:name="org.oxycblt.auxio.playback.PlaybackPanelFragment" android:name="org.oxycblt.auxio.playback.PlaybackPanelFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="org.oxycblt.auxio.ui.BottomSheetContentViewBehavior" /> app:layout_behavior="org.oxycblt.auxio.ui.BottomSheetContentBehavior" />
<LinearLayout <LinearLayout
android:id="@+id/queue_sheet" android:id="@+id/queue_sheet"

View file

@ -1,12 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<org.oxycblt.auxio.ui.recycler.EdgeRecyclerView <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/queue_recycler" android:id="@+id/queue_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:overScrollMode="ifContentScrolls"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" <org.oxycblt.auxio.ui.recycler.EdgeRecyclerView
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" android:id="@+id/queue_recycler"
tools:listitem="@layout/item_queue_song" /> android:layout_width="match_parent"
android:layout_height="match_parent"
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" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>

View file

@ -71,7 +71,7 @@
style="@style/Widget.Auxio.Button.Icon.Small" style="@style/Widget.Auxio.Button.Icon.Small"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_tiny" android:layout_marginEnd="@dimen/spacing_mid_medium"
android:contentDescription="@string/desc_queue_handle" android:contentDescription="@string/desc_queue_handle"
app:icon="@drawable/ic_handle_24" app:icon="@drawable/ic_handle_24"
app:layout_constraintBottom_toBottomOf="@+id/song_album_cover" app:layout_constraintBottom_toBottomOf="@+id/song_album_cover"

View file

@ -21,7 +21,7 @@
style="@style/Widget.Auxio.Button.Icon.Small" style="@style/Widget.Auxio.Button.Icon.Small"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_tiny" android:layout_marginEnd="@dimen/spacing_small"
android:contentDescription="@string/lbl_sort" android:contentDescription="@string/lbl_sort"
app:icon="@drawable/ic_sort_24" app:icon="@drawable/ic_sort_24"
app:layout_constraintBottom_toTopOf="@id/header_divider" app:layout_constraintBottom_toTopOf="@id/header_divider"