Search code examples
androidandroid-fragmentskotlinandroid-viewpager2

How to get Current Fragment in ViewPager2


i used this ViewPager2 dependency:

implementation 'androidx.viewpager2:viewpager2:1.0.0'

then i wrote code and make Adapter for FragmentStateAdapter like below:

private inner class ViewPagerAdapter(fragmentManager: FragmentManager,
                                         lifecycle: Lifecycle, config: TribunConfig?)
        : FragmentStateAdapter(fragmentManager, lifecycle) {
        private val config: TribunConfig?
        override fun createFragment(position: Int): Fragment {
            return TribunNewsFragment.newInstance(if (menuTribun!!.get(position) == "News") "home"
            else menuTribun!!.get(position)!!.replace(" ", "").toLowerCase(), config)!!
        }

        override fun getItemCount(): Int {
            return menuTribun!!.size
        }

        init {
            this.config = config
        }
    }

an in method onCreate i implement some code related viewpager2 and its adapter like below:

        viewPager2!!.offscreenPageLimit = 1
        viewPager2!!.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle, config)
        TabLayoutMediator(tabLayout!!, viewPager2!!, TabLayoutMediator.TabConfigurationStrategy { tab: TabLayout.Tab?, position: Int -> tab!!.text = menuTribun!!.get(position) }).attach()

But i have problem when i want to make swipeRefresh. My swipeRefresh needs current fragment to access the method inside fragment. But there is NO METHOD getItem in FragmentStateAdapter. Anyone can help me?


Solution

    1. Create property in your adapter to save all your fragments
    2. Save current position
    3. Get fragment from fragment list (property) by position when you need it

    Something like this:

        val fragments: MutableList<Fragment> = mutableListOf()
    
        private val config: TribunConfig?
        override fun createFragment(position: Int): Fragment {
            val fragment = TribunNewsFragment.newInstance(if (menuTribun!!.get(position) == "News") "home"
            else menuTribun!!.get(position)!!.replace(" ", "").toLowerCase(), config)!!
    
            fragments.add(fragment)
            return fragment
        }
    

    Parent:

     yourTabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                val fragment = adapter.fragments[tab!!.position]
                // cast fragment to your fragment class and do what you want
            }
    
            override fun onTabUnselected(tab: TabLayout.Tab?) {
            }
    
            override fun onTabReselected(tab: TabLayout.Tab?) {
            }
        })
    

    Also you can use when or if-else for your fragments position or create base class with methods you need and cast getting fragment to it.