6

I'm using Horizontal ViewPager2 which has 4 fragments inside. Each fragment has SwipeRefreshLayout on a RecyclerView. The issue that I'm facing is that when RecyclerView is at top position then onClick on any item is list is not working. If I scroll the RecyclerView a bit down then onClick works fine. And when RecyclerView is at top position then if SwipeRefreshLayout is in refreshing state then onClick works fine. It seems SwipeRefreshLayout is conflicting with ViewPager2 in touch events. It works fine with simple ViewPager. What could be the actual problem and how can we handle it? Any ideas would be appreciable.

Thanks

xml:

<androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/fragment_home"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >

            <include
                android:id="@+id/headerPanel"
                layout="@layout/home_header"
                app:viewModel="@{viewModel}" />

            <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
                android:id="@+id/swipe_refresh_layout"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:paddingStart="@dimen/home_post_side_spacing"
                android:paddingEnd="@dimen/home_post_side_spacing"
                app:colorScheme="@{@color/fayvo_color}"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/headerPanel"
                app:onRefreshListener="@{() -> viewModel.manualRefresh()}"
                app:refreshing="@{viewModel.isRefreshing}"
                android:background="#f0f0f0">

                <RelativeLayout
                    android:id="@+id/rl_rv"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/rv_homePosts"
                        adapter="@{viewModel.postObservableArrayList}"
                        addToTop="@{viewModel.addToTop}"
                        clearList="@{viewModel.clearList}"
                        showLoader="@{viewModel.isPagingEnabled &amp;&amp; viewModel.isLoading}"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

                    <FrameLayout
                        android:id="@+id/emptyFrameLayout"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:visibility="@{viewModel.showEmptyLayout?View.VISIBLE:View.GONE}" />

                    <include
                        android:id="@+id/postUploadProgressLayout"
                        layout="@layout/item_post_upload_progress"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        app:viewModel="@{viewModel}" />

                </RelativeLayout>
            </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>


            <View
                android:id="@+id/tooltipView"
                android:layout_width="1dp"
                android:layout_height=".1dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                />
        </androidx.constraintlayout.widget.ConstraintLayout>
Usman Rana
  • 2,067
  • 1
  • 21
  • 32

2 Answers2

4

I was also facing the same issue, it is due to nested scrolling. After a lot of searching i came to know that coordinator layout should be userd as parent layout. App bar also needs to be added and after that it should work perfectly. It resolved the issue.

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:id="@+id/coordinateLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/fragmentAppBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@null"
        app:elevation="0dp" />

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipeLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        >

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rvMemberList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            tools:listitem="@layout/holder_member_item" />

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

As i see you have also app bar so user constraint layout and include your app bar and coordinator layout inside that so hierarchy should be like

ConstraintLayout
  AppBar
  CoordinatorLayout
Abdul
  • 869
  • 6
  • 14
  • It worked. But ViewPager2 should handle it like simple ViewPager to keep view hierarchy simple. – Usman Rana Apr 09 '20 at 07:13
  • 1
    @Abdul I was facing another problem but this solution did the trick, The problem was when I reach the end of the RecyclerView and then touch the screen it slightly scroll up automatically hence will be available to be scrolled down again (the area that was scrolled up). Adding CoordinatorLayout with AppBarLayout help SwipeRefreshLayout to work properly. – Xexolas Apr 15 '20 at 03:27
  • Thanks a lot man, taking me a ton of time digging this issue, nice work around, but still need google to fix this bug. – Zijian Wang Jun 15 '20 at 15:03
  • With ConstraintLayout -> Coordinator -> SwipeRefresh -> Recycler - the click handler is only executed if the Coordinator layout has height="match_parent". If "0dp" or "match constraints" the click handler isn't invoked. This is no good for me as i need ConstraintLayout as a parent – OliverDeLange Sep 18 '20 at 13:59
1

A simpler solution is that Change Direct parent of ViewPager2 from CosntraintLayout to some other layout i.e. LinearLayout and it will work fine.

Usman Rana
  • 2,067
  • 1
  • 21
  • 32
  • Changing CosntraintLayout to some other layout i.e. LinearLayout is being suggested at few places but it didn't work for me. – Sharad Jul 02 '23 at 07:28