Merge pull request #5607 from abGit9/fix_stuttering_list_2

fix: resolve stuttering when scrolling to the bottom of channel/playlist videos list
This commit is contained in:
Bnyro 2024-02-25 12:56:20 +01:00 committed by GitHub
commit 066e01be51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 298 additions and 267 deletions

View File

@ -59,6 +59,8 @@ class ChannelFragment : DynamicLayoutManagerFragment() {
private var nextPages = Array<String?>(5) { null }
private var searchChannelAdapter: SearchChannelAdapter? = null
private var isAppBarFullyExpanded: Boolean = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
channelName = args.channelName
@ -86,14 +88,24 @@ class ChannelFragment : DynamicLayoutManagerFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Check if the AppBarLayout is fully expanded
binding.channelAppBar.addOnOffsetChangedListener { _, verticalOffset ->
isAppBarFullyExpanded = verticalOffset == 0
}
// Determine if the child can scroll up
binding.channelRefresh.setOnChildScrollUpCallback { _, _ ->
!isAppBarFullyExpanded
}
binding.channelRefresh.setOnRefreshListener {
fetchChannel()
}
binding.channelScrollView.viewTreeObserver.addOnScrollChangedListener {
binding.channelRecView.viewTreeObserver.addOnScrollChangedListener {
val binding = _binding ?: return@addOnScrollChangedListener
if (binding.channelScrollView.canScrollVertically(1) || isLoading) return@addOnScrollChangedListener
if (binding.channelRecView.canScrollVertically(1) || isLoading) return@addOnScrollChangedListener
loadNextPage()
}
@ -199,7 +211,8 @@ class ChannelFragment : DynamicLayoutManagerFragment() {
isLoading = false
binding.channelRefresh.isRefreshing = false
binding.channelScrollView.isVisible = true
binding.channelCoordinator.isVisible = true
binding.channelName.text = response.name
if (response.verified) {
binding.channelName

View File

@ -123,7 +123,6 @@ class PlaylistFragment : DynamicLayoutManagerFragment() {
}
private fun fetchPlaylist() {
binding.playlistScrollview.isGone = true
lifecycleScope.launch {
val response = try {
withContext(Dispatchers.IO) {
@ -136,12 +135,13 @@ class PlaylistFragment : DynamicLayoutManagerFragment() {
val binding = _binding ?: return@launch
playlistFeed = response.relatedStreams.toMutableList()
binding.playlistScrollview.isVisible = true
nextPage = response.nextpage
playlistName = response.name
isLoading = false
ImageHelper.loadImage(response.thumbnailUrl, binding.thumbnail)
binding.playlistProgress.isGone = true
binding.playlistAppBar.isVisible = true
binding.playlistRecView.isVisible = true
binding.playlistName.text = response.name
binding.playlistInfo.text = getChannelAndVideoString(response, response.videos)
@ -312,8 +312,8 @@ class PlaylistFragment : DynamicLayoutManagerFragment() {
}
})
binding.playlistScrollview.viewTreeObserver.addOnScrollChangedListener {
if (_binding?.playlistScrollview?.canScrollVertically(1) == false &&
binding.playlistRecView.viewTreeObserver.addOnScrollChangedListener {
if (_binding?.playlistRecView?.canScrollVertically(1) == false &&
!isLoading
) {
// append more playlists to the recycler view

View File

@ -6,18 +6,29 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/channel_scrollView"
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/channel_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="invisible"
tools:context=".ui.fragments.ChannelFragment">
android:visibility="gone">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/channel_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/channel_collapsing_tb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll"
app:titleCollapseMode="scale">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
app:layout_collapseMode="pin">
<ImageView
android:id="@+id/channel_banner"
@ -72,15 +83,15 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/channel_share"
android:tooltipText="@string/share"
style="@style/ElevatedIconButton"
android:tooltipText="@string/share"
app:icon="@drawable/ic_share"
tools:targetApi="m" />
<com.google.android.material.button.MaterialButton
android:id="@+id/notification_bell"
android:tooltipText="@string/notifications"
style="@style/ElevatedIconButton"
android:tooltipText="@string/notifications"
app:icon="@drawable/ic_notification"
tools:targetApi="m" />
@ -153,18 +164,17 @@
</HorizontalScrollView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
</LinearLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/channel_recView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false" />
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</com.github.libretube.ui.views.CustomSwipeToRefresh>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<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:layout_width="match_parent"
@ -10,14 +10,29 @@
android:id="@+id/playlist_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="gone" />
android:visibility="gone"
android:layout_gravity="center" />
<ScrollView
android:id="@+id/playlist_scrollview"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/playlist_recView"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:clipToPadding="false"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/playlist_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/playlist_collapsing_tb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll"
app:titleCollapseMode="scale">
<LinearLayout
android:layout_width="match_parent"
@ -137,21 +152,14 @@
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/playlist_recView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:nestedScrollingEnabled="false" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>