You need to start your migration with a FragmentStateAdapter. Example below
public class MonitorsViewPagerFragmentAdapter : FragmentStateAdapter
{
private readonly int itemCount;
//Refer to https://stackoverflow.com/questions/61779776/leak-canary-detects-memory-leaks-for-tablayout-with-viewpager2/62184494#62184494
public MonitorsViewPagerFragmentAdapter(FragmentManager fragmentManager, Lifecycle lifecylce, int itemCount) : base(fragmentManager, lifecylce)
{
this.itemCount = itemCount;
}
// implement inherited abstract member ItemCount
public override int ItemCount => itemCount;
// implement inherited abstract member - CreateFragment of Viewpager2 replaces GetItem of ViewPager. Creating a new instance each time instead of reusing instances as was done in ViewPager
public override Fragment CreateFragment(int position)
{
return position switch
{
0 => MonitorFragment.NewInstance(),
1 => ContinuousMonitoringFragment.NewInstance(),
2 => NonContinuousMonitoringFragment.NewInstance(),
_ => null,
};
}
}
Then in your parent fragment in your OnViewCreated you would instantiate the FragmentStateAdapter like the following lines
// FragmentStateAdapter - which calls CreateFragment for the three fragments - note the extra param ViewLifecycleOwner.Lifecycle
// Refer to https://stackoverflow.com/questions/61779776/leak-canary-detects-memory-leaks-for-tablayout-with-viewpager2/62184494#62184494
// This is using the third of the three FragmentStateAdapter public constructors.
// Note - it is also an abstract class, so we can add out own params. e.g. passing the total number of fragments that the ViewPager2 will hold.
monitorsViewPagerFragmentAdapter = new MonitorsViewPagerFragmentAdapter(ChildFragmentManager, ViewLifecycleOwner.Lifecycle, 3);
Then for your viewPager2
// Create a new ViewPager2.OnPageChangeCallback and then register with the ViewPager2 - must be unregistered in OnDestroy
monitorsViewPagerOnPageChangeCallback = new OnPageChangeCallback(Activity);
monitorsViewPager.RegisterOnPageChangeCallback(monitorsViewPagerOnPageChangeCallback);
monitorsViewPager.Orientation = ViewPager2.OrientationHorizontal;
// We need all three fragments in memory, setting OffscreenPageLimit=2 will achieve that
monitorsViewPager.OffscreenPageLimit = 2; // ViewPager2.OffscreenPageLimitDefault;
monitorsViewPager.Adapter = monitorsViewPagerFragmentAdapter;
Next the tabs
tabLayout.TabMode = TabLayout.ModeFixed;
tabLayout.TabGravity = TabLayout.GravityCenter;
TabLayoutMediator tabMediator = new TabLayoutMediator(tabLayout, monitorsViewPager, new TabConfigurationStrategy(Activity));
tabMediator.Attach();
An optional OnPageChangeCallback
class OnPageChangeCallback : ViewPager2.OnPageChangeCallback
{
// Don't really need this as we are not using it.
private readonly Context context;
public OnPageChangeCallback(Context context)
{
this.context = context;
}
public override void OnPageSelected(int position)
{
//Log.Debug(logTag, "OnPageSelected - SelectedItem " + selectedItem.ToString());
}
}
And a TabConfigurationStrategy
class TabConfigurationStrategy : Java.Lang.Object, TabLayoutMediator.ITabConfigurationStrategy
{
// using this for the tab titles
private readonly Context context;
public TabConfigurationStrategy(Context context)
{
this.context = context;
}
public void OnConfigureTab(TabLayout.Tab tab, int position)
{
tab.SetText(context.Resources.GetStringArray(Resource.Array.monitor_tab_titles)[position]);
}
}
See the following link for more information https://developer.android.com/training/animation/vp2-migration and follow the links in the code for more info.