1
0
Fork 0
mirror of https://github.com/MatomoCamp/matomocamp-companion-android.git synced 2024-09-19 16:13:46 +02:00

create viewLifecycleLazy and use it to make fragments properly implement RecycledViewPoolProvider

This commit is contained in:
Christophe Beyls 2020-04-21 14:42:36 +02:00
parent 96eb3df61d
commit 1d88941b63
4 changed files with 41 additions and 12 deletions

View file

@ -3,12 +3,13 @@ package be.digitalia.fosdem.fragments
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView.RecycledViewPool
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import be.digitalia.fosdem.R
import be.digitalia.fosdem.utils.enforceSingleScrollDirection
import be.digitalia.fosdem.utils.recyclerView
import be.digitalia.fosdem.utils.viewLifecycleLazy
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.tabs.TabLayoutMediator.TabConfigurationStrategy
@ -37,8 +38,9 @@ class LiveFragment : Fragment(R.layout.fragment_live), RecycledViewPoolProvider
}
}
override var recycledViewPool: RecycledViewPool? = null
private set
override val recycledViewPool by viewLifecycleLazy {
RecyclerView.RecycledViewPool()
}
private class LivePagerAdapter(fragment: Fragment)
: FragmentStateAdapter(fragment.childFragmentManager, fragment.viewLifecycleOwner.lifecycle) {

View file

@ -6,5 +6,5 @@ import androidx.recyclerview.widget.RecyclerView
* Components implementing this interface allow to share a RecycledViewPool between similar fragments.
*/
interface RecycledViewPoolProvider {
val recycledViewPool: RecyclerView.RecycledViewPool?
val recycledViewPool: RecyclerView.RecycledViewPool
}

View file

@ -9,7 +9,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.observe
import androidx.recyclerview.widget.RecyclerView.RecycledViewPool
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import be.digitalia.fosdem.R
@ -17,6 +17,7 @@ import be.digitalia.fosdem.db.AppDatabase
import be.digitalia.fosdem.model.Day
import be.digitalia.fosdem.utils.enforceSingleScrollDirection
import be.digitalia.fosdem.utils.recyclerView
import be.digitalia.fosdem.utils.viewLifecycleLazy
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.tabs.TabLayoutMediator.TabConfigurationStrategy
@ -40,7 +41,6 @@ class TracksFragment : Fragment(R.layout.fragment_tracks), RecycledViewPoolProvi
}
}
val daysAdapter = DaysAdapter(this)
recycledViewPool = RecycledViewPool()
var savedCurrentPage = if (savedInstanceState == null) {
// Restore the current page from preferences
@ -86,14 +86,10 @@ class TracksFragment : Fragment(R.layout.fragment_tracks), RecycledViewPoolProvi
})
}
override fun onDestroyView() {
super.onDestroyView()
recycledViewPool = null
override val recycledViewPool by viewLifecycleLazy {
RecyclerView.RecycledViewPool()
}
override var recycledViewPool: RecycledViewPool? = null
private set
private class DaysAdapter(fragment: Fragment)
: FragmentStateAdapter(fragment.childFragmentManager, fragment.viewLifecycleOwner.lifecycle) {

View file

@ -0,0 +1,31 @@
package be.digitalia.fosdem.utils
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
/**
* A Lazy implementation which can only be called when a fragment has a view
* and will automatically clear the value when the view hierarchy gets destroyed.
*/
fun <T : Any> Fragment.viewLifecycleLazy(initializer: () -> T): Lazy<T> = ViewLifecycleLazy(this, initializer)
class ViewLifecycleLazy<T : Any>(private val fragment: Fragment, private val initializer: () -> T) : Lazy<T> {
private var cached: T? = null
override val value: T
get() {
return cached ?: run {
val newValue = initializer()
cached = newValue
fragment.viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
cached = null
}
})
newValue
}
}
override fun isInitialized() = cached != null
}