0

I have the following code (borrowed from the sunflower app) :

const val FRAGMENT_A_PAGE_INDEX = 0
const val FRAGMENT_B_PAGE_INDEX = 1

class ViewPagerAdapter(fragment: Fragment): FragmentStateAdapter(fragment) {

    /**
     * Mapping of the ViewPager page indexes to their respective Fragments
     * */
    private val tabFragmentsCreators: Map<Int, () -> Fragment> = mapOf(
        FRAGMENT_A_PAGE_INDEX to { FragmentA() },
        FRAGMENT_B_PAGE_INDEX to { FragmentB() }
    )

    override fun getItemCount(): Int = tabFragmentsCreators.size

    override fun createFragment(position: Int): Fragment =
        tabFragmentsCreators[position]?.invoke() ?: throw IndexOutOfBoundsException()
}

So, in my host fragment controller hosting the viewpager above, I have the following:

class ViewPagerControllerFragment : Fragment() { 

     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
         binding = FragmentViewPagerControllerBinding.inflate(inflater, container, false)

         // set the adapter of the ViewPager2 widget
         binding.viewpager.adapter = ViewPagerAdapter(this)

         binding.lifecycleOwner = viewLifecycleOwner
         // inflate the layout for this fragment
         return binding.root
     }
     ... // NOT RELEVANT PARTS ARE SKIPPED ...
}

During a debug session, I saw that onCreateView() methods of FragmentA and FragmentB gets only called/invoked once. So, when FragmentA is visited the first time, the system invokes onCreateView() method of it. When I swipe to FragmentB and then back to FragmentA again, the onCreateView() is not invoked. Why is that so ? And how can I can change this so that it is invoked whenever I enter the Fragment?

class FragmentA : Fragment() {

    // gets called once
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { ... }

}

class FragmentB : Fragment() {

        // gets called once
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { ... }

    }
ebeninki
  • 909
  • 1
  • 12
  • 34
  • on create view() will be called only once. what you want to do in onCreateView() ? – Shalu T D Jun 06 '20 at 12:42
  • there is some code that should be run when we swipe to the Fragment. Should I put that code to onResume() when onCreateView() only called once ? – ebeninki Jun 06 '20 at 12:53

1 Answers1

0

Please try to use the below code:

Java Version:

viewPager.addOnPageChangeListener(new OnPageChangeListener() {
    public void onPageScrollStateChanged(int state) {}
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    public void onPageSelected(int position) {
        // put your code here
    }
});

Kotlin Version:-

 viewPager.registerOnPageChangeCallback(object : 
 ViewPager2.OnPageChangeCallback() {
    override fun onPageScrollStateChanged(state: Int) {
        println(state)
    }

    override fun onPageScrolled(
        position: Int,
        positionOffset: Float,
        positionOffsetPixels: Int
    ) {
        super.onPageScrolled(position, positionOffset, positionOffsetPixels)
        println(position)
    }


    override fun onPageSelected(position: Int) {
        super.onPageSelected(position)
        // put your code here
    }
})

When you swipe from one fragment to next, your viewPager2 OnPageChangeCallback will execute and you can identify the currently selected fragment from there.

Shalu T D
  • 3,921
  • 2
  • 26
  • 37