Recently, there was a demand that the customer wanted to add a drop-down refresh function. I see, this is not very simple. The SmartRefreshLayout control is introduced, and the layout can be written with a few swipes.
This is the main layout:
<?xml version="1.0" encoding="utf-8"?> <com.ggh.michat.widget.PagingRecyclerViewContainer xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:orientation="vertical"> <androidx.core.widget.NestedScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" android:scrollbars="none"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.tabs.TabLayout android:id="@+id/chat_square_tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" app:tabGravity="center" app:tabIndicatorFullWidth="false" app:tabIndicatorHeight="0dp" app:tabMode="scrollable" app:tabRippleColor="@android:color/transparent" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginEnd="@dimen/dp_10" android:src="@drawable/icon_select" /> </RelativeLayout> <cn.bingoogolapple.bgabanner.BGABanner android:id="@+id/banner" android:layout_width="match_parent" android:layout_height="150dp" android:layout_marginStart="@dimen/dp_10" android:layout_marginTop="@dimen/dp_10" android:layout_marginEnd="@dimen/dp_10" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/dp_10" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </LinearLayout> </androidx.core.widget.NestedScrollView> </com.ggh.michat.widget.PagingRecyclerViewContainer>
This is the recyclerView sub layout:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content_tv" android:layout_width="match_parent" android:layout_height="match_parent"> <com.scwang.smartrefresh.layout.SmartRefreshLayout android:id="@+id/refreshLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <com.scwang.smartrefresh.layout.header.ClassicsHeader android:layout_width="match_parent" android:layout_height="50dp" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" android:nestedScrollingEnabled="false" /> </com.scwang.smartrefresh.layout.SmartRefreshLayout> </FrameLayout>
After writing, the test is, uh, very good. There's no problem. It's over after writing.
...
The next day, open the familiar console and,???? All the data was loaded at once, and the paging function failed. Then I started the journey of finding bug s. It was found that the layout of NestedScrollView+ViewPager+RecyclerView led to the height of RecyclerView being increased all the time, which led to paging3 mistaking that the user had slid to the bottom, and then began to load the content of the next page until all the data was loaded..
According to the principle of solving bugs when encountering bugs, skillfully open the search engine and input: "NestedScrollView nested RecyclerView page loading invalid solution", start browsing the content and find the method. It is RecyclerView to add a Header, but the layout here is a tabLayout and a banner. Adding a Header is not appropriate. Then continue to find the method and find it again, It is to intercept the sliding event of NestedScrollView, and then distribute the event to the child View when sliding to the bottom. As soon as I see that this is feasible, I start my own series of operations.
After writing the test (the interception code will not be displayed if it is very watery), the sliding operation is OK, very good, but the sliding up! tabLayout and banner are not jacked up during fast sliding.. Failed.
Then I suddenly remembered that I looked at the CoordinatorLayout layout of the first line of code, thought that this layout combined with AppBarLayout seemed to completely solve my current problem, and then started a new wave of code..
It is feasible to test skillfully after writing! Completely solved the previous sliding conflict problem and paging3 failure problem!!
Below is the revised Code:
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.tabs.TabLayout android:id="@+id/chat_square_tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" app:layout_scrollFlags="scroll" app:tabGravity="center" app:tabIndicatorFullWidth="false" app:tabIndicatorHeight="0dp" app:tabMode="scrollable" app:tabRippleColor="@android:color/transparent" /> <ImageView android:id="@+id/select" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginEnd="@dimen/dp_10" android:padding="@dimen/dp_10" android:src="@drawable/icon_select" app:layout_scrollFlags="scroll" /> </RelativeLayout> <cn.bingoogolapple.bgabanner.BGABanner android:id="@+id/banner" android:layout_width="match_parent" android:layout_height="150dp" android:layout_marginStart="@dimen/dp_10" android:layout_marginTop="@dimen/dp_10" android:layout_marginEnd="@dimen/dp_10" app:layout_scrollFlags="scroll" /> </LinearLayout> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginEnd="@dimen/dp_10" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content_tv" android:layout_width="match_parent" android:layout_height="match_parent"> <com.scwang.smartrefresh.layout.SmartRefreshLayout android:id="@+id/refreshLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <com.scwang.smartrefresh.layout.header.ClassicsHeader android:layout_width="match_parent" android:layout_height="50dp" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </com.scwang.smartrefresh.layout.SmartRefreshLayout> </FrameLayout>
This is the test chart:
You can use the layout of CoordinatorLayout + AppBarLayout to replace the previous layout to achieve alternative solutions!
End