android – Toolbar Hide animation leaves behind empty layout-ThrowExceptions

Exception or error:

I’m trying to hide the toolbar when scrolling on a recycler view using a custom behavior animation (so that it matches the BottomNavigationView)

https://imgur.com/a/LauNxmc

Any tips on what’s causing this issue and how to fix it would be greatly appreciated

Here is some relevant code.

ToolbarHideBehavior.kt

class ToolbarHideBehavior<V : View?>(context: Context?, attrs: AttributeSet?) :Behavior<V>(context, attrs) {

companion object {
    private const val ENTER_ANIMATION_DURATION = 225
    private const val EXIT_ANIMATION_DURATION = 175
    private const val STATE_SCROLLED_DOWN = 1
    private const val STATE_SCROLLED_UP = 2
}

private var height = 0
private var currentState = STATE_SCROLLED_DOWN
private var additionalHiddenOffsetY = 0
private var currentAnimator: ViewPropertyAnimator? = null

override fun onLayoutChild(
    parent: CoordinatorLayout, child: V, layoutDirection: Int
): Boolean {
    val paramsCompat = child!!.layoutParams as MarginLayoutParams
    height = child.measuredHeight + paramsCompat.bottomMargin
    return super.onLayoutChild(parent, child, layoutDirection)
}


override fun onStartNestedScroll(
    coordinatorLayout: CoordinatorLayout,
    child: V,
    directTargetChild: View,
    target: View,
    nestedScrollAxes: Int
): Boolean {
    return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
}

override fun onNestedScroll(
    coordinatorLayout: CoordinatorLayout,
    child: V,
    target: View,
    dxConsumed: Int,
    dyConsumed: Int,
    dxUnconsumed: Int,
    dyUnconsumed: Int
) {
    if (dyConsumed > 0) {
        slideDown(child)
    } else if (dyConsumed < 0) {
        slideUp(child)
    }
}

/**
 * Perform an animation that will slide the child from it's current position to be completely on the
 * screen.
 */
private fun slideDown(child: V) {
    if (currentState == STATE_SCROLLED_UP) {
        return
    }
    if (currentAnimator != null) {
        currentAnimator!!.cancel()
        child!!.clearAnimation()
    }
    currentState = STATE_SCROLLED_UP
    animateChildTo(
        child,
        -(height + additionalHiddenOffsetY),
        ENTER_ANIMATION_DURATION.toLong(),
        AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR
    )
}

/**
 * Perform an animation that will slide the child from it's current position to be completely off the
 * screen.
 */
private fun slideUp(child: V) {
    if (currentState == STATE_SCROLLED_DOWN) {
        return
    }
    if (currentAnimator != null) {
        currentAnimator!!.cancel()
        child!!.clearAnimation()
    }
    currentState =
        STATE_SCROLLED_DOWN
    animateChildTo(
        child,
        0,
        EXIT_ANIMATION_DURATION.toLong(),
        AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR
    )
}

private fun animateChildTo(
    child: V, targetY: Int, duration: Long, interpolator: TimeInterpolator
) {
    currentAnimator = child?.animate()
        ?.translationY(targetY.toFloat())
        ?.setInterpolator(interpolator)
        ?.setDuration(duration)
        ?.setListener(
            object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    currentAnimator = null
                }
            })
}}

activity_main.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinator_main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ui.MainActivity">

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appBar_layout"
    android:layout_width="match_parent"
    app:layout_behavior="com.mlm09kdev.superHeroDB.utils.ToolbarHideBehavior"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:theme="@style/ToolbarTheme"
        app:layout_scrollFlags="scroll|enterAlways" />
</com.google.android.material.appbar.AppBarLayout>

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:defaultNavHost="true"
    app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
    app:navGraph="@navigation/nav_graph" />

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_nav"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:layout_alignParentBottom="true"
    app:itemIconTint="@color/navigation_color"
    app:itemTextColor="@color/navigation_color"
    android:background="@color/toolbar_background"
    android:layout_gravity="bottom"
    app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
    app:menu="@menu/bottom_nav" />
<!--app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" -->

How to solve:

Leave a Reply

Your email address will not be published. Required fields are marked *