Могу также опубликовать свое решение по этому поводу - это тот же базовый подход, что и у @Almighty, за исключением того, что я сохраняю Fragment
слабые ссылки в таблице поиска в PagerAdapter
:
private class PagerAdapter(fm: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fm, lifecycle) {
// only store as weak references, so you're not holding discarded fragments in memory
private val fragmentCache = mutableMapOf<Int, WeakReference<Fragment>>()
override fun getItemCount(): Int = tabList.size
override fun createFragment(position: Int): Fragment {
// return the cached fragment if there is one
fragmentCache[position]?.get()?.let { return it }
// no fragment found, time to make one - instantiate one however you
// like and add it to the cache
return tabList[position].fragment.newInstance()
.also { fragmentCache[position] = WeakReference(it) }
.also { Timber.d("Created a fragment! $it") }
}
// not necessary, but I think the code reads better if you
// can use a getter when you want to... try to get an existing thing
fun getFragment(position: Int) = createFragment(position)
}
а затем вы можете позвонить getFragment
, указав соответствующий номер страницы, например adapter.currentPage
или что-то еще.
Таким образом, адаптер сохраняет свой собственный кеш созданных фрагментов, но с WeakReference
s, поэтому он фактически не удерживает их, когда компоненты, фактически использующие фрагменты, будут с ними работать, они больше не будут в кеше. Таким образом, вы можете провести поиск всех текущих фрагментов.
Если хотите, вы можете заставить геттер просто возвращать результат поиска (допускающий значение NULL). Эта версия, очевидно, создает фрагмент, если он еще не существует, что полезно, если вы ожидаете, что он там будет. Это может быть удобно, если вы используете ViewPager2.OnPageChangeCallback
, который будет запускаться с новым номером страницы до, когда пейджер представления создаст фрагмент - вы можете получить страницу, которая создаст и кэширует ее, и когда пейджер вызывает createFragment
, он все еще должен быть в кеше, и его нельзя воссоздавать заново.
Тем не менее, не гарантируется, что слабая ссылка не будет собрана мусором между этими двумя моментами, поэтому, если вы устанавливаете что-то в этом экземпляре фрагмента (а не просто читаете что-то из него, например заголовок, вы хочу отобразить) имейте это в виду!
21.10.2020
childFragmentManager
. 27.05.2020"f"+yourID.toString()
@RuslanMyhal 23.07.2020ViewPager2
- это библиотека с открытым исходным кодом, не привязанная к платформе Android. В принципе, я не вижу причин для беспокойства @Dr. АНДРО 14.10.2020