mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Migrate library to ViewPager2
This commit is contained in:
		@@ -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'
 | 
			
		||||
 
 | 
			
		||||
@@ -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<LibraryAdapter.ViewHolder>() {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The categories to bind in the adapter.
 | 
			
		||||
@@ -28,45 +30,25 @@ class LibraryAdapter(private val controller: LibraryController) : RecyclerViewPa
 | 
			
		||||
 | 
			
		||||
    private var boundViews = arrayListOf<View>()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -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<View>()
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -39,7 +39,7 @@
 | 
			
		||||
            tools:text="Search"
 | 
			
		||||
            tools:visibility="visible" />
 | 
			
		||||
 | 
			
		||||
        <androidx.viewpager.widget.ViewPager
 | 
			
		||||
        <androidx.viewpager2.widget.ViewPager2
 | 
			
		||||
            android:id="@+id/library_pager"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="match_parent" />
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user