Search code examples
androidkotlinandroid-viewpager

Android Kotlin pass data from base fragment of a viewpager to one of its tab fragment


So in this case, I have a fragment that act as the base fragment for a viewpager consisting two tabs. What I want to do is to pass an information from the base fragment to one of it's tab fragment.

This is the snippet code of the base fragment

BaseFragment.kt

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    val args = arguments?.let { SwitchingHistoryDetailFragmentArgs.fromBundle(it) }

    val selectedOrderId = args?.orderId          //This variable is the one that i want to pass.

    // Set action bar title to "Main Dashboard"
    (activity as AppCompatActivity).supportActionBar?.title = "Switching History Details"

    val binding: FragmentSwitchingHistoryDetailBinding = DataBindingUtil.inflate(inflater,
        R.layout.fragment_switching_history_detail, container, false)


    Log.i("History", "Selected History: $selectedOrderId")


    binding.viewpagerMain.adapter =
        MyPagerAdapter((activity as AppCompatActivity).supportFragmentManager)
    binding.tabsMain.setupWithViewPager(viewpager_main)


    return binding.root
}

As you can see above, the variable that i want to pass is that selectedOrderId. This is the tab fragment that I want pass that information into:

DetailFragment.kt

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    // Binding object for this fragment and the layout
    binding = DataBindingUtil.inflate(inflater,
        R.layout.fragment_switching_history_detail_tab, container, false)

        ....
        ....
        ....

    //Return.... i don't know.
    return binding.root
}

And this is the PagerAdapter I'm using:

MyPagerAdapter.kt

class MyPagerAdapter(fm: FragmentManager): FragmentStatePagerAdapter(fm){

    // sebuah list yang menampung objek Fragment
    private val pages = listOf(
        DetailFragment(), <- This is where i want to pass the information into
        DetailFragment2()
    )

    // menentukan fragment yang akan dibuka pada posisi tertentu
    override fun getItem(position: Int): Fragment {
        return pages[position]
    }

    override fun getCount(): Int {
        return pages.size
    }

    // judul untuk tabs
    override fun getPageTitle(position: Int): CharSequence? {
        return when(position){
            0 -> "Details"
            else -> "Previous Changes"
        }
    }
}

I'm quite new with viewPager. I tried to use Intent but does not work. Is there a way to achieve this? If there's any detail i miss to point out, feel free to ask.


Solution

  • Simple way is pass the selectedOrderId into the adapter like below:

    binding.viewpagerMain.adapter =
            MyPagerAdapter((activity as AppCompatActivity).supportFragmentManager,selectedOrderId) 
    

    then pass that orderId from PagerAdapter to fragment constructor like below:

    class MyPagerAdapter(fm: FragmentManager,val orderId : String): FragmentStatePagerAdapter(fm){
    
        // sebuah list yang menampung objek Fragment
        private val pages = listOf(
            DetailFragment.getInstance(orderId), <- This is where i want to pass the information into
            DetailFragment2()
        )
    
        // menentukan fragment yang akan dibuka pada posisi tertentu
        override fun getItem(position: Int): Fragment {
            return pages[position]
        }
    
        override fun getCount(): Int {
            return pages.size
        }
    
        // judul untuk tabs
        override fun getPageTitle(position: Int): CharSequence? {
            return when(position){
                0 -> "Details"
                else -> "Previous Changes"
            }
        }
    }
    

    Your Detail fragment looks like :

    class DetailFragment : Fragment() { 
    
        private var orderId: String? = null
    
    
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
    
        // Binding object for this fragment and the layout
        binding = DataBindingUtil.inflate(inflater,
            R.layout.fragment_switching_history_detail_tab, container, false)
    
    
    
    if (arguments != null) {
                    orderId = arguments?.getString("orderId")
                }
    // do whatever you want to do with this variable
    
        return binding.root
    }
    
    companion object {      
    
            /**
             * Method used to get the instance of the fragment.
             *
             * @return fragment instance
             */
            @JvmStatic
            fun getInstance(orderId: String): DetailFragment {
                val fragment = DetailFragment()
                val bundle = Bundle()
                bundle.putString("orderId", orderId)
                fragment.arguments = bundle
                return fragment
            }
        }
    }
    

    LET ME KNOW IF YOU HAVE ANY DOUBT IN THIS. HAPPY CODING :)