Solution 1 :
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.
Problem :
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? { ... }
}
Comments
Comment posted by Shalu T D
on create view() will be called only once. what you want to do in onCreateView() ?
Comment posted by ebeninki
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 ?