Fix empty fragment list in fragment manager (#226)

This commit is contained in:
Rafał Borcz 2019-01-24 21:16:22 +01:00 committed by Mikołaj Pich
parent c78fb83774
commit d3c13b8fc3
8 changed files with 65 additions and 59 deletions

View File

@ -0,0 +1,36 @@
package io.github.wulkanowy.ui.base
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
class BaseFragmentPagerAdapter(private val fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {
private val pages = mutableMapOf<Fragment, String?>()
private var containerId = 0
fun getFragmentInstance(position: Int): Fragment? {
return fragmentManager.findFragmentByTag("android:switcher:$containerId:$position")
}
fun addFragments(fragments: List<Fragment>) {
fragments.forEach { pages[it] = null }
}
fun addFragmentsWithTitle(pages: Map<Fragment, String>) {
this.pages.putAll(pages)
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
containerId = container.id
return super.instantiateItem(container, position)
}
override fun getItem(position: Int) = pages.keys.elementAt(position)
override fun getCount() = pages.size
override fun getPageTitle(position: Int) = pages.values.elementAt(position)
}

View File

@ -1,32 +0,0 @@
package io.github.wulkanowy.ui.base
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
class BasePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
val fragments = mutableMapOf<String?, Fragment>()
val registeredFragments = mutableMapOf<Int, Fragment>()
override fun getItem(position: Int) = fragments.values.elementAt(position)
override fun getCount() = fragments.size
override fun getPageTitle(position: Int): CharSequence? {
return fragments.keys.elementAtOrNull(position)
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
return super.instantiateItem(container, position).also {
registeredFragments[position] = it as Fragment
}
}
override fun destroyItem(container: ViewGroup, position: Int, fragment: Any) {
registeredFragments.remove(position)
super.destroyItem(container, position, fragment)
}
}

View File

@ -11,7 +11,7 @@ import android.view.View.VISIBLE
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BasePagerAdapter import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.base.session.BaseSessionFragment import io.github.wulkanowy.ui.base.session.BaseSessionFragment
import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
@ -26,7 +26,7 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
lateinit var presenter: GradePresenter lateinit var presenter: GradePresenter
@Inject @Inject
lateinit var pagerAdapter: BasePagerAdapter lateinit var pagerAdapter: BaseFragmentPagerAdapter
companion object { companion object {
private const val SAVED_SEMESTER_KEY = "CURRENT_SEMESTER" private const val SAVED_SEMESTER_KEY = "CURRENT_SEMESTER"
@ -59,10 +59,11 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
} }
override fun initView() { override fun initView() {
pagerAdapter.fragments.putAll(mapOf( pagerAdapter.addFragmentsWithTitle(mapOf(
getString(R.string.all_details) to GradeDetailsFragment.newInstance(), GradeDetailsFragment.newInstance() to getString(R.string.all_details),
getString(R.string.grade_menu_summary) to GradeSummaryFragment.newInstance() GradeSummaryFragment.newInstance() to getString(R.string.grade_menu_summary)
)) ))
gradeViewPager.run { gradeViewPager.run {
adapter = pagerAdapter adapter = pagerAdapter
setOnSelectPageListener { presenter.onPageSelected(it) } setOnSelectPageListener { presenter.onPageSelected(it) }
@ -117,15 +118,15 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
} }
override fun notifyChildLoadData(index: Int, semesterId: Int, forceRefresh: Boolean) { override fun notifyChildLoadData(index: Int, semesterId: Int, forceRefresh: Boolean) {
(childFragmentManager.fragments[index] as GradeView.GradeChildView).onParentLoadData(semesterId, forceRefresh) (pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentLoadData(semesterId, forceRefresh)
} }
override fun notifyChildParentReselected(index: Int) { override fun notifyChildParentReselected(index: Int) {
(pagerAdapter.registeredFragments[index] as? GradeView.GradeChildView)?.onParentReselected() (pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentReselected()
} }
override fun notifyChildSemesterChange(index: Int) { override fun notifyChildSemesterChange(index: Int) {
(pagerAdapter.registeredFragments[index] as? GradeView.GradeChildView)?.onParentChangeSemester() (pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentChangeSemester()
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {

View File

@ -5,7 +5,7 @@ import dagger.Provides
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import io.github.wulkanowy.di.scopes.PerChildFragment import io.github.wulkanowy.di.scopes.PerChildFragment
import io.github.wulkanowy.di.scopes.PerFragment import io.github.wulkanowy.di.scopes.PerFragment
import io.github.wulkanowy.ui.base.BasePagerAdapter import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
@ -18,7 +18,7 @@ abstract class GradeModule {
@JvmStatic @JvmStatic
@PerFragment @PerFragment
@Provides @Provides
fun provideGradePagerAdapter(fragment: GradeFragment) = BasePagerAdapter(fragment.childFragmentManager) fun provideGradeAdapter(fragment: GradeFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager)
} }
@PerChildFragment @PerChildFragment

View File

@ -5,7 +5,7 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseActivity import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.base.BasePagerAdapter import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
import io.github.wulkanowy.ui.modules.login.options.LoginOptionsFragment import io.github.wulkanowy.ui.modules.login.options.LoginOptionsFragment
import io.github.wulkanowy.utils.setOnSelectPageListener import io.github.wulkanowy.utils.setOnSelectPageListener
@ -18,7 +18,7 @@ class LoginActivity : BaseActivity(), LoginView {
lateinit var presenter: LoginPresenter lateinit var presenter: LoginPresenter
@Inject @Inject
lateinit var loginAdapter: BasePagerAdapter lateinit var loginAdapter: BaseFragmentPagerAdapter
companion object { companion object {
fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java) fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java)
@ -36,9 +36,9 @@ class LoginActivity : BaseActivity(), LoginView {
} }
override fun initAdapter() { override fun initAdapter() {
loginAdapter.fragments.putAll(mapOf( loginAdapter.addFragments(listOf(
"1" to LoginFormFragment.newInstance(), LoginFormFragment.newInstance(),
"2" to LoginOptionsFragment.newInstance() LoginOptionsFragment.newInstance()
)) ))
loginViewpager.run { loginViewpager.run {
@ -52,7 +52,7 @@ class LoginActivity : BaseActivity(), LoginView {
} }
override fun notifyOptionsViewLoadData() { override fun notifyOptionsViewLoadData() {
(supportFragmentManager.fragments[1] as? LoginOptionsFragment)?.onParentLoadData() (loginAdapter.getFragmentInstance(1) as? LoginOptionsFragment)?.onParentLoadData()
} }
fun onChildFragmentSwitchOptions() { fun onChildFragmentSwitchOptions() {

View File

@ -5,7 +5,7 @@ import dagger.Provides
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import io.github.wulkanowy.di.scopes.PerActivity import io.github.wulkanowy.di.scopes.PerActivity
import io.github.wulkanowy.di.scopes.PerFragment import io.github.wulkanowy.di.scopes.PerFragment
import io.github.wulkanowy.ui.base.BasePagerAdapter import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
import io.github.wulkanowy.ui.modules.login.options.LoginOptionsFragment import io.github.wulkanowy.ui.modules.login.options.LoginOptionsFragment
@ -18,7 +18,7 @@ internal abstract class LoginModule {
@JvmStatic @JvmStatic
@PerActivity @PerActivity
@Provides @Provides
fun provideLoginAdapter(activity: LoginActivity) = BasePagerAdapter(activity.supportFragmentManager) fun provideLoginAdapter(activity: LoginActivity) = BaseFragmentPagerAdapter(activity.supportFragmentManager)
} }
@PerFragment @PerFragment

View File

@ -11,7 +11,7 @@ import io.github.wulkanowy.data.repositories.MessagesRepository.MessageFolder.RE
import io.github.wulkanowy.data.repositories.MessagesRepository.MessageFolder.SENT import io.github.wulkanowy.data.repositories.MessagesRepository.MessageFolder.SENT
import io.github.wulkanowy.data.repositories.MessagesRepository.MessageFolder.TRASHED import io.github.wulkanowy.data.repositories.MessagesRepository.MessageFolder.TRASHED
import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.base.BasePagerAdapter import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
import io.github.wulkanowy.utils.setOnSelectPageListener import io.github.wulkanowy.utils.setOnSelectPageListener
@ -24,7 +24,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
lateinit var presenter: MessagePresenter lateinit var presenter: MessagePresenter
@Inject @Inject
lateinit var pagerAdapter: BasePagerAdapter lateinit var pagerAdapter: BaseFragmentPagerAdapter
companion object { companion object {
fun newInstance() = MessageFragment() fun newInstance() = MessageFragment()
@ -46,11 +46,12 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
} }
override fun initView() { override fun initView() {
pagerAdapter.fragments.putAll(mapOf( pagerAdapter.addFragmentsWithTitle(mapOf(
getString(R.string.message_inbox) to MessageTabFragment.newInstance(RECEIVED), MessageTabFragment.newInstance(RECEIVED) to getString(R.string.message_inbox),
getString(R.string.message_sent) to MessageTabFragment.newInstance(SENT), MessageTabFragment.newInstance(SENT) to getString(R.string.message_sent),
getString(R.string.message_trash) to MessageTabFragment.newInstance(TRASHED) MessageTabFragment.newInstance(TRASHED) to getString(R.string.message_trash)
)) ))
messageViewPager.run { messageViewPager.run {
adapter = pagerAdapter adapter = pagerAdapter
offscreenPageLimit = 2 offscreenPageLimit = 2
@ -73,7 +74,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
} }
override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) { override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) {
(childFragmentManager.fragments[index] as MessageView.MessageChildView).onParentLoadData(forceRefresh) (pagerAdapter.getFragmentInstance(index) as? MessageView.MessageChildView)?.onParentLoadData(forceRefresh)
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@ -5,7 +5,7 @@ import dagger.Provides
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import io.github.wulkanowy.di.scopes.PerChildFragment import io.github.wulkanowy.di.scopes.PerChildFragment
import io.github.wulkanowy.di.scopes.PerFragment import io.github.wulkanowy.di.scopes.PerFragment
import io.github.wulkanowy.ui.base.BasePagerAdapter import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
@Module @Module
@ -17,7 +17,7 @@ abstract class MessageModule {
@JvmStatic @JvmStatic
@PerFragment @PerFragment
@Provides @Provides
fun provideGradePagerAdapter(fragment: MessageFragment) = BasePagerAdapter(fragment.childFragmentManager) fun provideMessageAdapter(fragment: MessageFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager)
} }
@PerChildFragment @PerChildFragment