fix: stuttering when scrolling in watch history

This commit is contained in:
Bnyro 2024-02-25 14:08:56 +01:00
parent c493ada148
commit 1257ed44b9
2 changed files with 110 additions and 91 deletions

View File

@ -30,6 +30,7 @@ import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.helpers.ProxyHelper import com.github.libretube.helpers.ProxyHelper
import com.github.libretube.ui.adapters.WatchHistoryAdapter import com.github.libretube.ui.adapters.WatchHistoryAdapter
import com.github.libretube.ui.base.DynamicLayoutManagerFragment import com.github.libretube.ui.base.DynamicLayoutManagerFragment
import com.github.libretube.ui.extensions.addOnBottomReachedListener
import com.github.libretube.ui.models.PlayerViewModel import com.github.libretube.ui.models.PlayerViewModel
import com.github.libretube.ui.sheets.BaseBottomSheet import com.github.libretube.ui.sheets.BaseBottomSheet
import com.github.libretube.util.PlayingQueue import com.github.libretube.util.PlayingQueue
@ -73,7 +74,8 @@ class WatchHistoryFragment : DynamicLayoutManagerFragment() {
} }
override fun setLayoutManagers(gridItems: Int) { override fun setLayoutManagers(gridItems: Int) {
_binding?.watchHistoryRecView?.layoutManager = GridLayoutManager(context, gridItems.ceilHalf()) _binding?.watchHistoryRecView?.layoutManager =
GridLayoutManager(context, gridItems.ceilHalf())
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -89,8 +91,10 @@ class WatchHistoryFragment : DynamicLayoutManagerFragment() {
if (allHistory.isEmpty()) return if (allHistory.isEmpty()) return
binding.filterTypeTV.text = resources.getStringArray(R.array.filterOptions)[selectedTypeFilter] binding.filterTypeTV.text =
binding.filterStatusTV.text = resources.getStringArray(R.array.filterStatusOptions)[selectedStatusFilter] resources.getStringArray(R.array.filterOptions)[selectedTypeFilter]
binding.filterStatusTV.text =
resources.getStringArray(R.array.filterStatusOptions)[selectedStatusFilter]
val watchPositionItem = arrayOf(getString(R.string.also_clear_watch_positions)) val watchPositionItem = arrayOf(getString(R.string.also_clear_watch_positions))
val selected = booleanArrayOf(false) val selected = booleanArrayOf(false)
@ -102,7 +106,7 @@ class WatchHistoryFragment : DynamicLayoutManagerFragment() {
selected[index] = newValue selected[index] = newValue
} }
.setPositiveButton(R.string.okay) { _, _ -> .setPositiveButton(R.string.okay) { _, _ ->
binding.historyScrollView.isGone = true binding.historyContainer.isGone = true
binding.historyEmpty.isVisible = true binding.historyEmpty.isVisible = true
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
Database.withTransaction { Database.withTransaction {
@ -179,7 +183,7 @@ class WatchHistoryFragment : DynamicLayoutManagerFragment() {
binding.watchHistoryRecView.adapter = watchHistoryAdapter binding.watchHistoryRecView.adapter = watchHistoryAdapter
binding.historyEmpty.isGone = true binding.historyEmpty.isGone = true
binding.historyScrollView.isVisible = true binding.historyContainer.isVisible = true
val itemTouchCallback = object : ItemTouchHelper.SimpleCallback( val itemTouchCallback = object : ItemTouchHelper.SimpleCallback(
0, 0,
@ -207,7 +211,7 @@ class WatchHistoryFragment : DynamicLayoutManagerFragment() {
RecyclerView.AdapterDataObserver() { RecyclerView.AdapterDataObserver() {
override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) { override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
if (watchHistoryAdapter.itemCount == 0) { if (watchHistoryAdapter.itemCount == 0) {
binding.historyScrollView.isGone = true binding.historyContainer.isGone = true
binding.historyEmpty.isVisible = true binding.historyEmpty.isVisible = true
} }
} }
@ -216,14 +220,13 @@ class WatchHistoryFragment : DynamicLayoutManagerFragment() {
// add a listener for scroll end, delay needed to prevent loading new ones the first time // add a listener for scroll end, delay needed to prevent loading new ones the first time
handler.postDelayed(200) { handler.postDelayed(200) {
if (_binding == null) return@postDelayed if (_binding == null) return@postDelayed
binding.historyScrollView.viewTreeObserver.addOnScrollChangedListener {
if (_binding?.historyScrollView?.canScrollVertically(1) == false && binding.watchHistoryRecView.addOnBottomReachedListener {
!isLoading if (isLoading) return@addOnBottomReachedListener
) {
isLoading = true isLoading = true
watchHistoryAdapter.showMoreItems() watchHistoryAdapter.showMoreItems()
isLoading = false isLoading = false
}
} }
} }
} }

View File

@ -28,90 +28,106 @@
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
<androidx.core.widget.NestedScrollView <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/historyScrollView" android:id="@+id/historyContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:scrollbars="vertical" android:scrollbars="vertical"
android:visibility="gone"> android:visibility="gone">
<LinearLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/playlist_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/play_all"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_weight="1"
android:maxLines="1"
android:text="@string/play_all"
app:icon="@drawable/ic_playlist" />
<com.google.android.material.button.MaterialButton
android:id="@+id/clear"
style="@style/Widget.Material3.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_weight="1"
android:maxLines="1"
android:text="@string/clear_history"
app:icon="@drawable/ic_delete" />
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp">
<TextView
android:id="@+id/filterTypeTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginStart="5dp"
android:drawablePadding="5dp"
android:paddingHorizontal="10dp"
android:text="@string/all"
android:textSize="16sp"
android:tooltipText="@string/tooltip_filter"
app:drawableEndCompat="@drawable/ic_filter" />
<TextView
android:id="@+id/filterStatusTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="5dp"
android:drawablePadding="5dp"
android:paddingHorizontal="10dp"
android:text="@string/watched"
android:textSize="16sp"
android:tooltipText="@string/tooltip_filter"
app:drawableEndCompat="@drawable/ic_filter" />
</FrameLayout>
</LinearLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/watchHistoryRecView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<LinearLayout </androidx.coordinatorlayout.widget.CoordinatorLayout>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/play_all"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_weight="1"
android:maxLines="1"
android:text="@string/play_all"
app:icon="@drawable/ic_playlist" />
<com.google.android.material.button.MaterialButton
android:id="@+id/clear"
style="@style/Widget.Material3.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_weight="1"
android:maxLines="1"
android:text="@string/clear_history"
app:icon="@drawable/ic_delete" />
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp">
<TextView
android:id="@+id/filterTypeTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginStart="5dp"
android:drawablePadding="5dp"
android:paddingHorizontal="10dp"
android:text="@string/all"
android:textSize="16sp"
android:tooltipText="@string/tooltip_filter"
app:drawableEndCompat="@drawable/ic_filter" />
<TextView
android:id="@+id/filterStatusTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="5dp"
android:drawablePadding="5dp"
android:paddingHorizontal="10dp"
android:text="@string/watched"
android:textSize="16sp"
android:tooltipText="@string/tooltip_filter"
app:drawableEndCompat="@drawable/ic_filter" />
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/watchHistoryRecView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:nestedScrollingEnabled="false" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</FrameLayout> </FrameLayout>