From d3c13b8fc3d7863054f513ff79b373abb52795d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Borcz?= <RafalBO99@outlook.com>
Date: Thu, 24 Jan 2019 21:16:22 +0100
Subject: [PATCH] Fix empty fragment list in fragment manager (#226)

---
 .../ui/base/BaseFragmentPagerAdapter.kt       | 36 +++++++++++++++++++
 .../wulkanowy/ui/base/BasePagerAdapter.kt     | 32 -----------------
 .../ui/modules/grade/GradeFragment.kt         | 17 ++++-----
 .../wulkanowy/ui/modules/grade/GradeModule.kt |  4 +--
 .../ui/modules/login/LoginActivity.kt         | 12 +++----
 .../wulkanowy/ui/modules/login/LoginModule.kt |  4 +--
 .../ui/modules/message/MessageFragment.kt     | 15 ++++----
 .../ui/modules/message/MessageModule.kt       |  4 +--
 8 files changed, 65 insertions(+), 59 deletions(-)
 create mode 100644 app/src/main/java/io/github/wulkanowy/ui/base/BaseFragmentPagerAdapter.kt
 delete mode 100644 app/src/main/java/io/github/wulkanowy/ui/base/BasePagerAdapter.kt

diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragmentPagerAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragmentPagerAdapter.kt
new file mode 100644
index 00000000..bccb8f78
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragmentPagerAdapter.kt
@@ -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)
+}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/BasePagerAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/base/BasePagerAdapter.kt
deleted file mode 100644
index 000efdcd..00000000
--- a/app/src/main/java/io/github/wulkanowy/ui/base/BasePagerAdapter.kt
+++ /dev/null
@@ -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)
-    }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt
index a4d948a9..d56eca9a 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt
@@ -11,7 +11,7 @@ import android.view.View.VISIBLE
 import android.view.ViewGroup
 import androidx.appcompat.app.AlertDialog
 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.modules.grade.details.GradeDetailsFragment
 import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
@@ -26,7 +26,7 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
     lateinit var presenter: GradePresenter
 
     @Inject
-    lateinit var pagerAdapter: BasePagerAdapter
+    lateinit var pagerAdapter: BaseFragmentPagerAdapter
 
     companion object {
         private const val SAVED_SEMESTER_KEY = "CURRENT_SEMESTER"
@@ -59,10 +59,11 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
     }
 
     override fun initView() {
-        pagerAdapter.fragments.putAll(mapOf(
-            getString(R.string.all_details) to GradeDetailsFragment.newInstance(),
-            getString(R.string.grade_menu_summary) to GradeSummaryFragment.newInstance()
+        pagerAdapter.addFragmentsWithTitle(mapOf(
+            GradeDetailsFragment.newInstance() to getString(R.string.all_details),
+            GradeSummaryFragment.newInstance() to getString(R.string.grade_menu_summary)
         ))
+
         gradeViewPager.run {
             adapter = pagerAdapter
             setOnSelectPageListener { presenter.onPageSelected(it) }
@@ -117,15 +118,15 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
     }
 
     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) {
-        (pagerAdapter.registeredFragments[index] as? GradeView.GradeChildView)?.onParentReselected()
+        (pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentReselected()
     }
 
     override fun notifyChildSemesterChange(index: Int) {
-        (pagerAdapter.registeredFragments[index] as? GradeView.GradeChildView)?.onParentChangeSemester()
+        (pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentChangeSemester()
     }
 
     override fun onSaveInstanceState(outState: Bundle) {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeModule.kt
index c47ddc57..b7b52f21 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeModule.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeModule.kt
@@ -5,7 +5,7 @@ import dagger.Provides
 import dagger.android.ContributesAndroidInjector
 import io.github.wulkanowy.di.scopes.PerChildFragment
 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.summary.GradeSummaryFragment
 
@@ -18,7 +18,7 @@ abstract class GradeModule {
         @JvmStatic
         @PerFragment
         @Provides
-        fun provideGradePagerAdapter(fragment: GradeFragment) = BasePagerAdapter(fragment.childFragmentManager)
+        fun provideGradeAdapter(fragment: GradeFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager)
     }
 
     @PerChildFragment
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
index c9c1aeb4..db3124e4 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
@@ -5,7 +5,7 @@ import android.content.Intent
 import android.os.Bundle
 import io.github.wulkanowy.R
 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.options.LoginOptionsFragment
 import io.github.wulkanowy.utils.setOnSelectPageListener
@@ -18,7 +18,7 @@ class LoginActivity : BaseActivity(), LoginView {
     lateinit var presenter: LoginPresenter
 
     @Inject
-    lateinit var loginAdapter: BasePagerAdapter
+    lateinit var loginAdapter: BaseFragmentPagerAdapter
 
     companion object {
         fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java)
@@ -36,9 +36,9 @@ class LoginActivity : BaseActivity(), LoginView {
     }
 
     override fun initAdapter() {
-        loginAdapter.fragments.putAll(mapOf(
-            "1" to LoginFormFragment.newInstance(),
-            "2" to LoginOptionsFragment.newInstance()
+        loginAdapter.addFragments(listOf(
+            LoginFormFragment.newInstance(),
+            LoginOptionsFragment.newInstance()
         ))
 
         loginViewpager.run {
@@ -52,7 +52,7 @@ class LoginActivity : BaseActivity(), LoginView {
     }
 
     override fun notifyOptionsViewLoadData() {
-        (supportFragmentManager.fragments[1] as? LoginOptionsFragment)?.onParentLoadData()
+        (loginAdapter.getFragmentInstance(1) as? LoginOptionsFragment)?.onParentLoadData()
     }
 
     fun onChildFragmentSwitchOptions() {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginModule.kt
index 3cdf8367..1758d59a 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginModule.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginModule.kt
@@ -5,7 +5,7 @@ import dagger.Provides
 import dagger.android.ContributesAndroidInjector
 import io.github.wulkanowy.di.scopes.PerActivity
 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.options.LoginOptionsFragment
 
@@ -18,7 +18,7 @@ internal abstract class LoginModule {
         @JvmStatic
         @PerActivity
         @Provides
-        fun provideLoginAdapter(activity: LoginActivity) = BasePagerAdapter(activity.supportFragmentManager)
+        fun provideLoginAdapter(activity: LoginActivity) = BaseFragmentPagerAdapter(activity.supportFragmentManager)
     }
 
     @PerFragment
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt
index f75c6131..df6ceca7 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt
@@ -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.TRASHED
 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.message.tab.MessageTabFragment
 import io.github.wulkanowy.utils.setOnSelectPageListener
@@ -24,7 +24,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
     lateinit var presenter: MessagePresenter
 
     @Inject
-    lateinit var pagerAdapter: BasePagerAdapter
+    lateinit var pagerAdapter: BaseFragmentPagerAdapter
 
     companion object {
         fun newInstance() = MessageFragment()
@@ -46,11 +46,12 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
     }
 
     override fun initView() {
-        pagerAdapter.fragments.putAll(mapOf(
-            getString(R.string.message_inbox) to MessageTabFragment.newInstance(RECEIVED),
-            getString(R.string.message_sent) to MessageTabFragment.newInstance(SENT),
-            getString(R.string.message_trash) to MessageTabFragment.newInstance(TRASHED)
+        pagerAdapter.addFragmentsWithTitle(mapOf(
+            MessageTabFragment.newInstance(RECEIVED) to getString(R.string.message_inbox),
+            MessageTabFragment.newInstance(SENT) to getString(R.string.message_sent),
+            MessageTabFragment.newInstance(TRASHED) to getString(R.string.message_trash)
         ))
+
         messageViewPager.run {
             adapter = pagerAdapter
             offscreenPageLimit = 2
@@ -73,7 +74,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
     }
 
     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() {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageModule.kt
index dd7a22ae..e4c202d9 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageModule.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageModule.kt
@@ -5,7 +5,7 @@ import dagger.Provides
 import dagger.android.ContributesAndroidInjector
 import io.github.wulkanowy.di.scopes.PerChildFragment
 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
 
 @Module
@@ -17,7 +17,7 @@ abstract class MessageModule {
         @JvmStatic
         @PerFragment
         @Provides
-        fun provideGradePagerAdapter(fragment: MessageFragment) = BasePagerAdapter(fragment.childFragmentManager)
+        fun provideMessageAdapter(fragment: MessageFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager)
     }
 
     @PerChildFragment