Search code examples
androidkotlinandroid-fragmentsandroid-viewpager2

How to recreate or refresh fragment while swiping ViewPager2 tabs


I have a viewpager2 with FragmentStateAdapter() adapter inside it. I also have a tab layout with 4 tabs. I use a single fragment for all tab. that is named AllOrdersTab. in my architecture I just send different value to load different API data to AllOrdersTab fragment. when each tab layout is selected , a fragment created and works fine for the first time for all 4 fragments. after that if I swipe back to previous tab it is not created or refreshed again. I want to recreate the fragment or a way to call API again when swiping between tabs. I also read this page.

FragmentStateAdapter not recreating currentFragment after notifyDataSetChanged

I tried to do this. so I decided to create 4 instance of Allorderstab() fragment. but never work for me because I guess hash codes of fragments are same.

ViewPager2 Adapter:

class ViewPagerOrdersAdapter(fm: FragmentManager,val listFragments:MutableList<Fragment>, viewlifecycler: Lifecycle) : FragmentStateAdapter(fm, viewlifecycler)
{

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

    override fun createFragment(position: Int): Fragment {
        val args = Bundle()

        when (position) {
            1 -> {
                args.putString("KEY_ID", "inProgress")
                listFragments[position].arguments = args
                return listFragments[position]
            }
            2 -> {
                args.putString("KEY_ID", "cancel")
                listFragments[position].arguments = args
                return listFragments[position]
            }
            3 ->
            {
             args.putString("KEY_ID","deliver")
                listFragments[position].arguments=args
                return listFragments[position]
            }
            else -> {
                args.putString("KEY_ID", "all")
                listFragments[position].arguments = args
                return listFragments[position]
            }
        }

    }

    override fun getItemId(position: Int): Long {
        return   listFragments[position].hashCode().toLong()
    }

    override fun containsItem(itemId: Long): Boolean {

        return listFragments.find {it.id.hashCode().toLong() == itemId } != null
    }


}

Here I created 4 instance of Allorderstab() Fragment.

Set ViewPager2 Adapter MainFragment:

    val fragments:MutableList<Fragment> = mutableListOf(Allorderstab(), Allorderstab(), Allorderstab(), Allorderstab())

    vp.setAdapter(ViewPagerOrdersAdapter(this.childFragmentManager,fragments, lifecycle))

AllOrderstab Fragment:

override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?, savedInstanceState: Bundle?): View? {
 val bundle = arguments
       bundle?.let {
           val myStatus = bundle.getString("KEY_ID")
           myStatus?.let{
               //getting history of each tab orders - calling API
               myviewModel.getOrdersHistory(tempTn,myStatus)
           }
       }
}

All in all I don't know how to refresh while swiping between tabs . if I have a single fragment for all 4 tabs.


Solution

  • For those who wasted a day for this problem like me , wanting to call API each time for refreshing data, Move your code to onResume function. fortunately it is run each time your fragment visible.

    AllOrderstab Fragment:

    override fun onResume() {
        val bundle = arguments
        bundle?.let {
            val myStatus = bundle.getString("KEY_ID")
            myStatus?.let{
                //getting history of all orders
                myviewModel.getOrdersHistory(tempTn,myStatus)
            }
        }
    
        super.onResume()
    }