Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically animate BottomSheet peekHeight

Did anyone manage to animate a BottomSheet peekHeight?

I currently do the following:

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

The bottomsheet peek height is changed, but I would like to have an animation, like when you change the state from STATE_COLLAPSED to STATE_EXPANDED.

like image 948
Ambi Avatar asked Nov 02 '17 16:11

Ambi


3 Answers

I was able to accomplish this by using RxJava and the Interval operator that runs every 15 milliseconds and changing the peekHeight every time the interval occurred.

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
                })
like image 143
Will Avatar answered Oct 29 '22 09:10

Will


Too late here but someone looking for a simpler solution - Kotlin and ObjectAnimator.

Following will animate the bottomsheet from peekHeight 0dp to R.dimen.login_bottomSheet_peak_height for 1000ms

ObjectAnimator.ofInt(bottomSheetBehavior, "peekHeight",
            resources.getDimension(R.dimen.login_bottomSheet_peak_height).toInt())
            .apply {
                duration = 1000
                start()
            }
like image 5
Adil Khalil Avatar answered Oct 29 '22 07:10

Adil Khalil


I managed to animate peekHeight changing using following code:

   private fun changePeek(height: Int) {
       behavior?.state = BottomSheetBehavior.STATE_HIDDEN
       behavior?.peekHeight = height
       behavior?.state = BottomSheetBehavior.STATE_COLLAPSED
   }
like image 3
cora32 Avatar answered Oct 29 '22 09:10

cora32