androidkotlinfragmentfragmentpageradapter

How to change fragment inside getItem of FragmentStatePagerAdapter


I have this code, where I want the first fragment of my FragmentStatePageAdapter(inside a viewpager), to change, depending on some boolean values.

inner class MainFragmentAdapter(fragmentManager: FragmentManager) :
        FragmentStatePagerAdapter(fragmentManager) {

    override fun getCount(): Int {
        return MainView.Fragments.values().size
    }

    override fun getItem(position: Int): Fragment? {
        return when (position) {
            0 -> {
                if (booleanOne && !booleanTwo) {
                    FragmentOne.newInstance()
                } else if (booleanTwo && !booleanOne) {
                    FragmentTwo.newInstance()
                } else {
                    FragmentThree.newInstance()
                }
            }
            else -> null
        }
    }
}

As of now, the only solution I found, was when I personally knew one of the boolean values changed, I just did something similar to this :

   _fragmentAdapter = MainFragmentAdapter(getLifecycleFragmentManager())

   fragmentViewPager.adapter = _fragmentAdapter

So I just set the adapter once again, but it seems rather off to me to do this. Can't I force it to just calculate getItem once again?


Solution

  • Inside your class make these changes, notifyDataSetChanged() and then override the getItemPosition() which will be called on every notify and then just return the respective constant, POSITION_NONE if you want to see new changes or else POSITION_UNCHANGED

        inner class MainFragmentAdapter(fragmentManager: FragmentManager) :
            FragmentStatePagerAdapter(fragmentManager) {
    
        override fun getCount(): Int {
            return MainView.Fragments.values().size
        }
    
        override fun getItem(position: Int): Fragment? {
            return when (position) {
                0 -> {
                    if (booleanOne && !booleanTwo) {
                        FragmentOne.newInstance()
                    } else if (booleanTwo && !booleanOne) {
                        FragmentTwo.newInstance()
                    } else {
                        FragmentThree.newInstance()
                    }
                   notifyDataSetChanged();
                }
                else -> null
            }
        }
    
        override fun getItemPosition(@NonNull `object`: Any): Int {
                // this method will be called for every fragment in the ViewPager
                return if (`object` is FragmentOne) {
                    POSITION_UNCHANGED // don't force a reload
                } else {
                    // POSITION_NONE means something like: this fragment is no longer valid
                    // triggering the ViewPager to re-build the instance of this fragment.
                    POSITION_NONE
                }
            }
    
    }