23

我已经尝试过BottomSheetBehaviour使用设计库23.0.2的新功能,但我认为它太有限了。当我使用setState()方法更改状态时,底页使用广告动画移动到新状态。

如何在没有动画的情况下立即更改状态?我没有看到这样做的公共方法。

4

3 回答 3

5

不幸的是,看起来你不能。的调用以BottomSheetBehaviorsetState同步或异步调用结束startSettlingAnimation(child, state)。并且没有办法覆盖这些方法行为原因setState是最终的并且startSettlingAnimation具有包可见修饰符。检查来源以获取更多信息。

我也有同样的问题,但方式有点不同——setHideable在调用稳定动画之前,我的 UI 状态变为 false,所以我到了IllegalStateException那里。我会考虑使用BottomSheetCallback来正确管理它。

于 2016-12-08T12:18:32.133 回答
1

如果要删除显示/关闭动画,可以使用dialog.window?.setWindowAnimations(-1). 例如:

class MyDialog(): BottomSheetDialogFragment() {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState)

        dialog.window?.setDimAmount(0f) // for removing the dimm
        dialog.window?.setWindowAnimations(-1) // for removing the animation

        return dialog
    }
}
于 2021-01-03T17:39:40.370 回答
0

如果你真的需要它,那么你可以求助于反射:

  fun BottomSheetBehavior.getViewDragHelper(): ViewDragHelper? = BottomSheetBehavior::class.java
    .getDeclaredField("viewDragHelper")
    .apply { isAccessible = true }
    .let { field -> field.get(this) as? ViewDragHelper? }

  fun ViewDragHelper.getScroller(): OverScroller? = ViewDragHelper::class.java
    .getDeclaredField("mScroller")
    .apply { isAccessible = true }
    .let { field -> field.get(this) as? OverScroller? }

然后你可以在状态改变时使用这些扩展方法:

  bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetCallback() {
      override fun onSlide(view: View, offset: Float) {}

      override fun onStateChanged(view: View, state: Int) {
        if (state == STATE_SETTLING) {
           try { 
              bottomSheetBehavior.getViewDragHelper()?.getScroller()?.abortAnimation()
           } catch(e: Throwable) {}
        }
      }
    })

我要补充一点,代码并不完美,每次状态变化时获取字段效率不高,这样做是为了简单起见。

于 2020-08-18T18:43:31.430 回答