Description:
BottomSheetBehavior#state is not updated correctly if it was updated during the BottomSheetBehavior.SETTLING state. BottomSheetCallback$onStateChanged is not called with the correct value either.
Visually, the sheet is in the proper state.
Expected behavior:
BottomSheetBehavior#state should match its visual state and BottomSheetCallback#onStateChanged should be called with the latest state change.
Source code:
Sample project: BottomSheetDemo.zip
Snippet to reproduce bug:
class BottomSheetView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) : FrameLayout(context, attrs, defStyleAttr, defStyleRes), CoordinatorLayout.AttachedBehavior {
private val bottomSheetBehavior = BottomSheetBehavior<BottomSheetView>()
init {
// Initialize sheet to be hidden and set callback for when the state changes
bottomSheetBehavior.isHideable = true
bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(p0: View, p1: Float) = Unit
override fun onStateChanged(p0: View, p1: Int) {
println("state changed $p1")
}
})
updateState(BottomSheetBehavior.STATE_HIDDEN)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
// Update state to be expanded (from hidden)
postDelayed({
updateState(BottomSheetBehavior.STATE_EXPANDED)
// Update state to be hidden (from expanded during the settling animation)
postDelayed({
updateState(BottomSheetBehavior.STATE_HIDDEN)
// Query the state of the sheet after animation completes
postDelayed({
println("query state ${bottomSheetBehavior.state}")
}, 1000)
}, 300)
}, 3000)
}
private fun updateState(state: Int) {
println("update state to $state")
bottomSheetBehavior.state = state
}
override fun getBehavior(): CoordinatorLayout.Behavior<BottomSheetView> = bottomSheetBehavior
}
On 1.1.0-alpha03 and newer versions (including 1.1.0-alpha09), the above outputs:
update state to 5
update state to 3
state changed 2
update state to 5
state changed 3
query state 3
On 1.0.0, the above outputs:
update state to 5
update state to 3
state changed 2
update state to 5
state changed 3
state changed 5
query state 5
The sheet's end state should be HIDDEN (5), but it returns EXPANDED (3).
Android API version: Reproducible on API 21 (Lollipop) and 29 (Q Beta)
Material Library version: 1.1.0-alpha09
Device: Nexus 5X emulator and Pixel 3
I'm observing same behavior as well
I notice this behavior as well.
Seeing the same bug here as well
Thanks for reporting this! We're actively working on a fix for this issue now
Thanks @melaniegoetz
Hi @melaniegoetz, just checking in if you have an expected timeline for this fix. Thanks.
Hi there! The fix was submitted and synced out in (e057829) and will be included in the next alpha release
Gracias @melaniegoetz, appreciate your help here!
I can still observe incorrect behavior with material-components version 1.2.0.
The state change seems to be ignored when changing the state to BottomSheetBehavior.STATE_EXPANDED while the bottom sheet is currently settling.
The following workaround seems to solve the issue:
private fun expandBottomSheet() {
+ if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_SETTLING) {
+ // workaround for https://github.com/material-components/material-components-android/issues/516
+ handler.removeCallbacksAndMessages(null)
+ handler.postDelayed({ expandBottomSheet() }, 10)
+ } else {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
+ }
}
Most helpful comment
I can still observe incorrect behavior with material-components version
1.2.0.The state change seems to be ignored when changing the state to
BottomSheetBehavior.STATE_EXPANDEDwhile the bottom sheet is currently settling.The following workaround seems to solve the issue: