From 577cc848eea6d34999cfc69b31c9527fc495f698 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sat, 28 Oct 2023 15:26:22 +0300 Subject: [PATCH] Scroll lists to top atomatically --- .../core/ui/list/RecyclerScrollKeeper.kt | 40 +++++++++++++++++++ .../download/ui/list/DownloadsActivity.kt | 2 + .../kotatsu/history/ui/HistoryListFragment.kt | 2 + 3 files changed, 44 insertions(+) create mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/core/ui/list/RecyclerScrollKeeper.kt diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/list/RecyclerScrollKeeper.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/list/RecyclerScrollKeeper.kt new file mode 100644 index 000000000..b6d651e46 --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/list/RecyclerScrollKeeper.kt @@ -0,0 +1,40 @@ +package org.koitharu.kotatsu.core.ui.list + +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver + +class RecyclerScrollKeeper( + private val rv: RecyclerView, +) : AdapterDataObserver() { + + private val scrollUpRunnable = Runnable { + (rv.layoutManager as? LinearLayoutManager)?.scrollToPositionWithOffset(0, 0) + } + + fun attach() { + rv.adapter?.registerAdapterDataObserver(this) + } + + override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { + super.onItemRangeInserted(positionStart, itemCount) + if (positionStart == 0 && isScrolledToTop()) { + postScrollUp() + } + } + + override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) { + super.onItemRangeMoved(fromPosition, toPosition, itemCount) + if (toPosition == 0 && isScrolledToTop()) { + postScrollUp() + } + } + + private fun postScrollUp() { + rv.postDelayed(scrollUpRunnable, 500L) + } + + private fun isScrolledToTop(): Boolean { + return (rv.layoutManager as? LinearLayoutManager)?.findFirstVisibleItemPosition() == 0 + } +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt index f01eb4803..e7487bbc8 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt @@ -15,6 +15,7 @@ import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.list.ListSelectionController +import org.koitharu.kotatsu.core.ui.list.RecyclerScrollKeeper import org.koitharu.kotatsu.core.ui.util.MenuInvalidator import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.util.ext.observe @@ -53,6 +54,7 @@ class DownloadsActivity : BaseActivity(), addItemDecoration(decoration) adapter = downloadsAdapter selectionController.attachToRecyclerView(this) + RecyclerScrollKeeper(this).attach() } addMenuProvider(DownloadsMenuProvider(this, viewModel)) viewModel.items.observe(this) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt index 56837477a..ed6a4718e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt @@ -9,6 +9,7 @@ import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.os.NetworkManageIntent import org.koitharu.kotatsu.core.ui.list.ListSelectionController +import org.koitharu.kotatsu.core.ui.list.RecyclerScrollKeeper import org.koitharu.kotatsu.core.util.ext.addMenuProvider import org.koitharu.kotatsu.databinding.FragmentListBinding import org.koitharu.kotatsu.list.ui.MangaListFragment @@ -23,6 +24,7 @@ class HistoryListFragment : MangaListFragment() { override fun onViewBindingCreated(binding: FragmentListBinding, savedInstanceState: Bundle?) { super.onViewBindingCreated(binding, savedInstanceState) + RecyclerScrollKeeper(binding.recyclerView).attach() addMenuProvider(HistoryListMenuProvider(binding.root.context, viewModel)) }