2

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

Chris Su
  • 233
  • 3
  • 9

2 Answers2

7

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) {
        }
    })
Tarik Husin
  • 197
  • 2
  • 9
1

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

Chris Su
  • 233
  • 3
  • 9