动态动画BottomSheet的peekHeight

9

请问有人成功地将BottomSheet的peekHeight动画化了吗?

我目前采用以下方法:

        bottom_sheet?.let {
            val behavior = BottomSheetBehavior.from(bottom_sheet)
            behavior.peekHeight = 500
            behavior.state = BottomSheetBehavior.STATE_COLLAPSED
        }

底部弹出窗口的预览高度已更改,但我希望有一个动画效果,就像从STATE_COLLAPSED状态更改为STATE_EXPANDED时一样。

你解决了吗? - Chandra Sekhar
不,我开始使用AndroidSlidingUpPanel。 - Ambi
5个回答

5
我使用 RxJava 和 Interval 运算符来实现这一点,它每 15 毫秒运行一次,并在每次间隔发生时更改 peekHeight。
val interpolator = AccelerateDecelerateInterpolator()
val refreshInterval = 20L
val refreshCount = 15L
val totalRefreshTime = (refreshInterval * refreshCount).toFloat()
val startingHeight = bottomSheetBehavior.peekHeight

animationDisposable = Observable.interval(refreshInterval, TimeUnit.MILLISECONDS)
                .take(refreshCount)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ count: Long ->
                    if (show) {
                        val height = (startingHeight + (maxPeekHeight - minPeekHeight) *
                                interpolator.getInterpolation((count * refreshInterval) / totalRefreshTime)).toInt()
                        if (height > maxPeekHeight) {
                            bottomSheetBehavior.peekHeight = maxPeekHeight
                        } else {
                            bottomSheetBehavior.peekHeight = height
                        }

                    } else {
                        val height = (startingHeight - (maxPeekHeight - minPeekHeight) *
                                interpolator.getInterpolation((count * refreshInterval) / totalRefreshTime)).toInt()

                        if (height < minPeekHeight) {
                            bottomSheetBehavior.peekHeight = minPeekHeight
                        } else {
                            bottomSheetBehavior.peekHeight = height
                        }
                    }
                }, { _: Throwable ->
                    //do something here to reset peek height to original
                })

5

虽然已经晚了,但有人正在寻找一种更简单的解决方案——使用Kotlin和ObjectAnimator。

以下代码将以1000毫秒的动画时间将底部操作表从peekHeight 0dp动画到R.dimen.login_bottomSheet_peak_height。

ObjectAnimator.ofInt(bottomSheetBehavior, "peekHeight",
            resources.getDimension(R.dimen.login_bottomSheet_peak_height).toInt())
            .apply {
                duration = 1000
                start()
            }

1
我正在替换底部表中的不同片段,如何使浏览从当前位置到新位置动画平滑过渡,即使新位置比当前位置更大或更小。 - Tony George

3

我成功地使用以下代码实现了peekHeight的动画效果:

   private fun changePeek(height: Int) {
       behavior?.state = BottomSheetBehavior.STATE_HIDDEN
       behavior?.peekHeight = height
       behavior?.state = BottomSheetBehavior.STATE_COLLAPSED
   }

实际上起作用了。谢谢! - Cristian-Leonard Miehs

3

@cora32的回答是正确的;

我只是想在他们的回答中补充一些内容。如果您防止底部表单隐藏(例如使用app:behavior_hideable =“false”),则使用该代码将导致非法状态异常。

要在任何情况下动画显示您的peekHeight,只需执行以下操作:

BottomSheetBehavior.from(bottomSheetView)?.apply {
    state = BottomSheetBehavior.STATE_EXPANDED
    peekHeight = newHeight
    state = BottomSheetBehavior.STATE_COLLAPSED
}

1

我认为通过使用ValueAnimator(C#),我已经让它正常工作:

private BottomSheetBehavior bsh;

public void AnimToNewHeight(int newHeight)
{
    LinearLayout bottomSheet = (LinearLayout)FindViewById(Resource.Id.bottom_sheet);
    BottomSheetBehavior behavior = BottomSheetBehavior.From(bottomSheet);

    bsh = behavior;

    ValueAnimator anim = new ValueAnimator();
    anim.SetIntValues(bsh.PeekHeight,newHeight);
    anim.SetDuration(300);
    anim.Update += Anim_Update;
    anim.Start();
}

private void Anim_Update(object sender, ValueAnimator.AnimatorUpdateEventArgs e)
{
    float f = e.Animation.AnimatedFraction;
    bsh.PeekHeight =(int)(e.Animation.AnimatedValue);
}

所以它在每个帧中都设置一个新的高度?这对我来说似乎不正确。 - barnacle.m

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接