Search code examples
androidkotlinandroid-viewpager

ViewPager activates its fragments before usage


I'm using a ViewPager to slide between different fragments as tabs. I noticed that just by creating the adapter, the onCreateView function inside each fragment is being called immediately, which is no good since I would like to run the code inside these functions at a specific given time.

My code in MainActivity:

private var profileTab: TabLayout.Tab? = null
    private var swipeTab: TabLayout.Tab? = null
    private var matchesTab: TabLayout.Tab? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        profileTab = navigationTabs.newTab()
        swipeTab = navigationTabs.newTab()
        matchesTab = navigationTabs.newTab()

        navigationTabs.addTab(profileTab!!)
        navigationTabs.addTab(swipeTab!!)
        navigationTabs.addTab(matchesTab!!)

        val adapter = PagerAdapter(supportFragmentManager, navigationTabs.tabCount)
        fragmentContainer.adapter = adapter

My code of PagerAdapter.kt:

class PagerAdapter (fm: FragmentManager, private val mNoOfTabs: Int) : FragmentStatePagerAdapter(fm, mNoOfTabs) {

    override fun getItem(position: Int): Fragment {
        when (position) {
            0 -> {
                return ProfileFragment()
            }
            1 -> {
                return SwipeFragment()
            }
            2 -> {
                return MatchesFragment()
            }
        }
        return null!!
    }

    override fun getCount() = mNoOfTabs
}

And in activity_main.xml (if it matters):

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/navigationTabs"
        android:layout_width="match_parent"
        android:layout_height="@dimen/navigation_height"
        android:background="@drawable/navigation_shadow"
        app:layout_constraintTop_toTopOf="parent"
        app:tabIndicator="@null"
        app:tabMinWidth="@dimen/navigation_height"
        app:tabRippleColor="@null" />

<!--    // the fragment will be displayed here:-->
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/navigationTabs"/>

Is this the default behavior? Can it be prevented, so that the fragments won't be initiated immediately?


Solution

  • ViewPager will initialize two fragments minimally. ViewPager allows us to set setOffscreenPageLimit(), but it require at least 1, so it will initialize first and next fragment. Read more here ViewPager.setOffscreenPageLimit(0) doesn't work as expected

    Try to invoke code in fragments by setting onPageChangedListener() in MainActivity, so you can execute code when user swiped/opened fragment.