From fe38c70d34def7d260e87e7c658a0e3b29b0ecd0 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Mon, 8 Aug 2022 16:22:03 -0600 Subject: [PATCH] ui: don't re-inset content only Revert the changes I made in 0474940ee3e67f4c72822c644439fd03e3f899be and return to the hybrid layout + inset system. The big issue is edge effects and touch events. I need to properly clamp edge effects to the padding, but that also requires me to use stretch edge effects everywhere to prevent weird visual isuses. This may happen in the future in RecyclerView 1.3.0, but development on such has been minimal. Meanwhile, touch events will be intercepted by the now overlapping view if one clicks the wrong portion of the bar. Nothing I can do given how touch events are intercepted by the bottom sheet, at least right now. More feasible to keep the current system and mitigate whatever issues are present there. --- .../auxio/playback/PlaybackSheetBehavior.kt | 11 ---- .../auxio/ui/BottomSheetContentBehavior.kt | 52 ++++++++++++++----- 2 files changed, 39 insertions(+), 24 deletions(-) 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 4ecb45c67..d6e6a1b44 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt @@ -24,9 +24,7 @@ import android.view.MotionEvent import android.view.View import androidx.coordinatorlayout.widget.CoordinatorLayout import com.google.android.material.shape.MaterialShapeDrawable -import com.google.android.material.shape.ShapeAppearanceModel import org.oxycblt.auxio.R -import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.ui.AuxioSheetBehavior import org.oxycblt.auxio.util.getAttrColorCompat import org.oxycblt.auxio.util.getDimen @@ -42,15 +40,6 @@ class PlaybackSheetBehavior(context: Context, attributeSet: AttributeS MaterialShapeDrawable.createWithElevationOverlay(context).apply { fillColor = context.getAttrColorCompat(R.attr.colorSurface) elevation = context.getDimen(R.dimen.elevation_normal) - - if (Settings(context).roundMode) { - val cornersMedium = context.getDimen(R.dimen.size_corners_medium) - shapeAppearanceModel = - ShapeAppearanceModel.Builder() - .setTopLeftCornerSize(cornersMedium) - .setTopRightCornerSize(cornersMedium) - .build() - } } init { diff --git a/app/src/main/java/org/oxycblt/auxio/ui/BottomSheetContentBehavior.kt b/app/src/main/java/org/oxycblt/auxio/ui/BottomSheetContentBehavior.kt index 19a8319cd..bac1ae091 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/BottomSheetContentBehavior.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/BottomSheetContentBehavior.kt @@ -24,13 +24,13 @@ import android.view.WindowInsets import androidx.coordinatorlayout.widget.CoordinatorLayout import com.google.android.material.bottomsheet.NeoBottomSheetBehavior import kotlin.math.abs -import kotlin.math.max import org.oxycblt.auxio.util.coordinatorLayoutBehavior import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat import org.oxycblt.auxio.util.systemBarInsetsCompat /** - * A behavior that automatically re-insets content to align with the parent layout's bottom sheet. + * A behavior that automatically re-layouts and re-insets content to align with the parent layout's + * bottom sheet. * @author OxygenCobalt */ class BottomSheetContentBehavior(context: Context, attributeSet: AttributeSet?) : @@ -60,10 +60,20 @@ class BottomSheetContentBehavior(context: Context, attributeSet: Attri return false } - lastConsumed = consumed - lastInsets?.let(child::dispatchApplyWindowInsets) + if (consumed != lastConsumed) { + lastConsumed = consumed + + val insets = lastInsets + if (insets != null) { + child.dispatchApplyWindowInsets(insets) + } + + lastInsets?.let(child::dispatchApplyWindowInsets) + measureContent(parent, child, consumed) + layoutContent(child) + return true + } - // Re-insetting views does not lead to the child view changing size or position. return false } @@ -75,19 +85,21 @@ class BottomSheetContentBehavior(context: Context, attributeSet: Attri parentHeightMeasureSpec: Int, heightUsed: Int ): Boolean { - val contentWidthSpec = - View.MeasureSpec.makeMeasureSpec(parent.measuredWidth, View.MeasureSpec.EXACTLY) - val contentHeightSpec = - View.MeasureSpec.makeMeasureSpec(parent.measuredHeight, View.MeasureSpec.EXACTLY) + val dep = dep ?: return false + val behavior = dep.coordinatorLayoutBehavior as NeoBottomSheetBehavior + val consumed = behavior.calculateConsumedByBar() + if (consumed == Int.MIN_VALUE) { + return false + } - child.measure(contentWidthSpec, contentHeightSpec) + measureContent(parent, child, consumed) return true } override fun onLayoutChild(parent: CoordinatorLayout, child: V, layoutDirection: Int): Boolean { super.onLayoutChild(parent, child, layoutDirection) - child.layout(0, 0, child.measuredWidth, child.measuredHeight) + layoutContent(child) if (!setup) { child.setOnApplyWindowInsetsListener { v, insets -> @@ -100,9 +112,9 @@ class BottomSheetContentBehavior(context: Context, attributeSet: Attri } val bars = insets.systemBarInsetsCompat - val newBottom = max(bars.bottom, consumed) - insets.replaceSystemBarInsetsCompat(bars.left, bars.top, bars.right, newBottom) + insets.replaceSystemBarInsetsCompat( + bars.left, bars.top, bars.right, (bars.bottom - consumed).coerceAtLeast(0)) } setup = true @@ -111,6 +123,20 @@ class BottomSheetContentBehavior(context: Context, attributeSet: Attri return true } + private fun measureContent(parent: View, child: View, consumed: Int) { + val contentWidthSpec = + View.MeasureSpec.makeMeasureSpec(parent.measuredWidth, View.MeasureSpec.EXACTLY) + val contentHeightSpec = + View.MeasureSpec.makeMeasureSpec( + parent.measuredHeight - consumed, View.MeasureSpec.EXACTLY) + + child.measure(contentWidthSpec, contentHeightSpec) + } + + private fun layoutContent(child: View) { + child.layout(0, 0, child.measuredWidth, child.measuredHeight) + } + private fun NeoBottomSheetBehavior<*>.calculateConsumedByBar(): Int { val offset = calculateSlideOffset() if (offset == Float.MIN_VALUE || peekHeight < 0) {