Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When I doing some animation in MotionLayout with RecyclerView and SwipeRefreshLayout that thing getting weird

I was using MotionLayout to achieve some cool effect when RecyclerView drag up, but it looks like when I want to use SwipeRefreshLayout with RecyclerView, things getting conflict.

If no SwipeRefreshLayout, it was fine

If I surround with SwipeRefreshLayout, drag up behavior was weird like opposed

https://gist.github.com/GHChrisSu/6aadf40dc693bc47cbb83a167a82a4b9

And the motion scene is below

https://gist.github.com/GHChrisSu/a154d59f34555cccfc1b48617989ae16

like image 396
Chris Su Avatar asked Dec 09 '25 09:12

Chris Su


2 Answers

You should wrap your MotionLayout in a SwipeRefreshLayout like this:

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/refresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/motion_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layoutDescription="@xml/play_scene">

                <!-- Some xml code -->

            </androidx.constraintlayout.motion.widget.MotionLayout>

        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

And then you must add a MotionLayout.TransitionListener to your MotionLayout to enable/disable your SwipeRefreshLayout depending on the MotionLayout state.

binding.motionLayout.setTransitionListener(object :MotionLayout.TransitionListener{
        override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {

        }

        override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
        }

        override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
            Log.d("RepairsFragment","$p1 $p2 $p3")
            if (p3 == 0f) {
                binding.refresh.isEnabled=true
            } else {
                binding.refresh.isEnabled = false
                binding.refresh.isRefreshing=false
            }
        }

        override fun onTransitionCompleted(p0: MotionLayout?, p1: Int) {
        }
    })
like image 100
Tarik Husin Avatar answered Dec 10 '25 21:12

Tarik Husin


I finally solve this by wrap the SwipeRefreshLayout out of the motionlayout, and change the state of SwipeRefreshLayout in onTransitionChange function to deal with this issue

like image 28
Chris Su Avatar answered Dec 10 '25 22:12

Chris Su