From 2a202bd510bf667153a40eea9bd641172533f603 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 19 Jul 2020 11:48:41 -0400 Subject: [PATCH] Migrate library to ViewPager2 --- app/build.gradle | 3 +- .../tachiyomi/ui/library/LibraryAdapter.kt | 69 ++++++------------- .../tachiyomi/ui/library/LibraryController.kt | 14 ++-- .../widget/RecyclerViewPagerAdapter.kt | 34 --------- .../main/res/layout/library_controller.xml | 2 +- 5 files changed, 34 insertions(+), 88 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/widget/RecyclerViewPagerAdapter.kt diff --git a/app/build.gradle b/app/build.gradle index 0187c4676..6bce19cea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -143,6 +143,7 @@ dependencies { implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha04' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' + implementation "androidx.viewpager2:viewpager2:1.0.0" implementation 'androidx.webkit:webkit:1.3.0-rc01' final lifecycle_version = '2.3.0-alpha05' @@ -259,7 +260,7 @@ dependencies { implementation "io.github.reactivecircus.flowbinding:flowbinding-appcompat:$flowbinding_version" implementation "io.github.reactivecircus.flowbinding:flowbinding-recyclerview:$flowbinding_version" implementation "io.github.reactivecircus.flowbinding:flowbinding-swiperefreshlayout:$flowbinding_version" - implementation "io.github.reactivecircus.flowbinding:flowbinding-viewpager:$flowbinding_version" + implementation "io.github.reactivecircus.flowbinding:flowbinding-viewpager2:$flowbinding_version" // Licenses final aboutlibraries_version = '8.2.0' diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryAdapter.kt index 27bb23182..d13efe42e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryAdapter.kt @@ -1,18 +1,20 @@ package eu.kanade.tachiyomi.ui.library +import android.content.Context +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import eu.kanade.tachiyomi.R +import androidx.recyclerview.widget.RecyclerView import eu.kanade.tachiyomi.data.database.models.Category -import eu.kanade.tachiyomi.util.view.inflate -import eu.kanade.tachiyomi.widget.RecyclerViewPagerAdapter +import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding /** * This adapter stores the categories from the library, used with a ViewPager. - * - * @constructor creates an instance of the adapter. */ -class LibraryAdapter(private val controller: LibraryController) : RecyclerViewPagerAdapter() { +class LibraryAdapter( + private val context: Context, + private val controller: LibraryController +) : RecyclerView.Adapter() { /** * The categories to bind in the adapter. @@ -28,45 +30,25 @@ class LibraryAdapter(private val controller: LibraryController) : RecyclerViewPa private var boundViews = arrayListOf() - /** - * Creates a new view for this adapter. - * - * @return a new view. - */ - override fun createView(container: ViewGroup): View { - val view = container.inflate(R.layout.library_category) as LibraryCategoryView - view.onCreate(controller) - return view + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val binding = LibraryCategoryBinding.inflate(LayoutInflater.from(context), parent, false) + binding.root.onCreate(controller) + return ViewHolder(binding) } - /** - * Binds a view with a position. - * - * @param view the view to bind. - * @param position the position in the adapter. - */ - override fun bindView(view: View, position: Int) { - (view as LibraryCategoryView).onBind(categories[position]) + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val view = (holder.itemView as LibraryCategoryView) + view.onBind(categories[position]) boundViews.add(view) } - /** - * Recycles a view. - * - * @param view the view to recycle. - * @param position the position in the adapter. - */ - override fun recycleView(view: View, position: Int) { - (view as LibraryCategoryView).onRecycle() + override fun onViewRecycled(holder: ViewHolder) { + val view = (holder.itemView as LibraryCategoryView) + view.onRecycle() boundViews.remove(view) } - /** - * Returns the number of categories. - * - * @return the number of categories or 0 if the list is null. - */ - override fun getCount(): Int { + override fun getItemCount(): Int { return categories.size } @@ -76,19 +58,10 @@ class LibraryAdapter(private val controller: LibraryController) : RecyclerViewPa * @param position the position of the element. * @return the title to display. */ - override fun getPageTitle(position: Int): CharSequence { + fun getPageTitle(position: Int): CharSequence { return categories[position].name } - /** - * Returns the position of the view. - */ - override fun getItemPosition(obj: Any): Int { - val view = obj as? LibraryCategoryView ?: return POSITION_NONE - val index = categories.indexOfFirst { it.id == view.category.id } - return if (index == -1) POSITION_NONE else index - } - /** * Called when the view of this adapter is being destroyed. */ @@ -99,4 +72,6 @@ class LibraryAdapter(private val controller: LibraryController) : RecyclerViewPa } } } + + class ViewHolder(binding: LibraryCategoryBinding) : RecyclerView.ViewHolder(binding.root) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 21315cad3..d1b8004dc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -15,6 +15,7 @@ import androidx.core.graphics.drawable.DrawableCompat import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeType import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayoutMediator import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.PublishRelay import com.tfcporciuncula.flow.Preference @@ -45,7 +46,7 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import reactivecircus.flowbinding.android.view.clicks import reactivecircus.flowbinding.appcompat.queryTextChanges -import reactivecircus.flowbinding.viewpager.pageSelections +import reactivecircus.flowbinding.viewpager2.pageSelections import rx.Subscription import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -164,7 +165,8 @@ class LibraryController( override fun onViewCreated(view: View) { super.onViewCreated(view) - adapter = LibraryAdapter(this) + adapter = LibraryAdapter(activity!!, this) + binding.libraryPager.offscreenPageLimit = 5 binding.libraryPager.adapter = adapter binding.libraryPager.pageSelections() .onEach { @@ -212,7 +214,11 @@ class LibraryController( override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { super.onChangeStarted(handler, type) if (type.isEnter) { - activity?.tabs?.setupWithViewPager(binding.libraryPager) + activity?.tabs?.let { tabLayout -> + TabLayoutMediator(tabLayout, binding.libraryPager) { tab, position -> + tab.text = adapter?.getPageTitle(position) + }.attach() + } presenter.subscribeLibrary() } } @@ -333,10 +339,8 @@ class LibraryController( val position = binding.libraryPager.currentItem - adapter.recycle = false binding.libraryPager.adapter = adapter binding.libraryPager.currentItem = position - adapter.recycle = true } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/RecyclerViewPagerAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/RecyclerViewPagerAdapter.kt deleted file mode 100644 index 2e1d51c2f..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/RecyclerViewPagerAdapter.kt +++ /dev/null @@ -1,34 +0,0 @@ -package eu.kanade.tachiyomi.widget - -import android.view.View -import android.view.ViewGroup -import com.nightlynexus.viewstatepageradapter.ViewStatePagerAdapter -import java.util.Stack - -abstract class RecyclerViewPagerAdapter : ViewStatePagerAdapter() { - - private val pool = Stack() - - var recycle = true - set(value) { - if (!value) pool.clear() - field = value - } - - protected abstract fun createView(container: ViewGroup): View - - protected abstract fun bindView(view: View, position: Int) - - protected open fun recycleView(view: View, position: Int) {} - - override fun createView(container: ViewGroup, position: Int): View { - val view = if (pool.isNotEmpty()) pool.pop() else createView(container) - bindView(view, position) - return view - } - - override fun destroyView(container: ViewGroup, position: Int, view: View) { - recycleView(view, position) - if (recycle) pool.push(view) - } -} diff --git a/app/src/main/res/layout/library_controller.xml b/app/src/main/res/layout/library_controller.xml index 75fdb112c..a01e595ec 100644 --- a/app/src/main/res/layout/library_controller.xml +++ b/app/src/main/res/layout/library_controller.xml @@ -39,7 +39,7 @@ tools:text="Search" tools:visibility="visible" /> -