ui: don't re-inset content only

Revert the changes I made in 0474940ee3
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.
This commit is contained in:
OxygenCobalt 2022-08-08 16:22:03 -06:00
parent 46473ceff9
commit fe38c70d34
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
2 changed files with 39 additions and 24 deletions

View file

@ -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<V : View>(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 {

View file

@ -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<V : View>(context: Context, attributeSet: AttributeSet?) :
@ -60,10 +60,20 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
return false
}
if (consumed != lastConsumed) {
lastConsumed = consumed
lastInsets?.let(child::dispatchApplyWindowInsets)
// Re-insetting views does not lead to the child view changing size or position.
val insets = lastInsets
if (insets != null) {
child.dispatchApplyWindowInsets(insets)
}
lastInsets?.let(child::dispatchApplyWindowInsets)
measureContent(parent, child, consumed)
layoutContent(child)
return true
}
return false
}
@ -75,19 +85,21 @@ class BottomSheetContentBehavior<V : View>(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<V : View>(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<V : View>(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) {