I am relatively new to using ViewPager, so I may be missing something else, but here is the best description I can come up with. My PagerAdapter is not expected to have very many items (during my tests, it only has 4), and prior to assigning the adapter to the ViewPager I set OffscreenPageLimit to the number of items that will be in the adapter. When I need to update the ViewPager, I assign a new instance of the PagerAdapter to the ViewPager's Adapter. However, this is causing a Java.Lang.NullPointerException in the DestroyItem method of my PagerAdapter. Here is my DestroyItem:
public override void DestroyItem(ViewGroup container, int position, Object @object) { container.RemoveViewAt(position); }
I am not sure what I should be putting in DestroyItem, especially since I am creating a new instance of the PagerAdapter anyway. What is the problem? Should I be doing something different in DestroyItem?
Hello,
Welcome to our Microsoft Q&A platform!
If you create custom
FragmentPagerAdapter
, you do not need to override the
DestroyItem
to recycle fragments manually.
The default for the
setOffScreenPageLimit
should already be one. This means that Android will destroy old fragments when memory runs low. As long as you do not have a memory issue, just leave it be.
If you want to recycle other disappeared Fragments automatically, you can extend
FragmentStatePagerAdapter
, Entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to
FragmentPagerAdapter
at the cost of potentially more overhead when switching between pages.
Here is a document about achieving a custom FragmentPagerAdapter in Xamarin. You can refer to it.
https://learn.microsoft.com/en-us/xamarin/android/user-interface/controls/view-pager/viewpager-and-fragments#create-the-adapter
If FragmentStateAdapter is deprecated,
Switch to androidx.viewpager2.widget.ViewPager2 and use androidx.viewpager2.adapter.FragmentStateAdapter instead.
If you want to use ViewPager2, you need to install Xamarin.AndroidX.ViewPager2nuget package:
Best Regards,
Leon Lu
If the answer is the right solution, please click "
Accept Answer
" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our
documentation
to enable e-mail notifications if you want to receive the related email notification for this thread.
You talk about using a FragmentPagerAdapter, is there a way to do this when inheriting from a regular PagerAdapter? I can attempt to convert to a FragmentPagerAdapter, I have not done this because I have never used Fragments before. Is there an appropriate way to override DestroyItem, or is FragmentPagerAdapter my only option?
The link you give is for the support library version of ViewPager, I was hoping to use the AndroidX version, but I could not find any good tutorials for the AndroidX version for Xamarin.Android. If there is no alternative, I am willing to attempt to learn & use Fragments, but since it would be my first time using Fragments for anything, and my only experience with ViewPager is what I have done so far with this one (which means I have never finished a complete app that uses a ViewPager). Are there any good AndroidX tutorials for ViewPager with Fragments?
FragmentPagerAdapter and FragmentStatePagerAdapter extends PagerAdapter, So I suggest you to use FragmentPagerAdapter and FragmentStatePagerAdapter directly. FragmentPagerAdapter and FragmentStatePagerAdapter
have achieved recycle fragment function, you do not need to override DestoryItems.
For AndroidX. You can use
AndroidX.Fragment.App
namespace that contains Fragment,FragmentPagerAdapter and FragmentStatePagerAdapter etc.
If you want to use ViewPage in Androidx, please add this
<androidx.viewpager.widget.ViewPager>
tag in the xml layout.
Switch to
androidx.viewpager2.widget.ViewPager2
and use
androidx.viewpager2.adapter.FragmentStateAdapter
instead.
If you want to use ViewPager2, you need to install
Xamarin.AndroidX.ViewPager2
nuget package:
Typical of support here, too many recommendations of using outdated techniques. You shouldn't really waste your time with ViewPager, you should be using ViewPager2. See AndroidX.ViewPager2.Widget which uses FragmentStateAdapter. There are plenty of Android ViewPager2 and FragmentStateAdapter tutorials around.
That is only somewhat correct. I did decide to use ViewPager2, although I switched back to using the non-fragment version, since as I said I am inexperienced with Fragments, and have experience with RecyclerView. There are lots of ViewPager2 tutorials, but they are not in C# & Xamarin.Android. Although it is not in C#, the fact that I managed to (I think) understand ViewPager with Views, using the tutorial at
https://developer.android.com/training/animation/vp2-migration
helped me manage to convert to ViewPager2. I like the fact that ViewPager2 is based on RecyclerView, because it allows me to do things in ways I am more familiar with. I will plead guilty to procrastinating learning Fragments, because I know they are important, but for now, this is good.
ViewPager2 will certainly work with Activities, however, I wouldn't waste time with multi-activity development because modern android development is Single Activity/multiple fragments using the Navigation component.
So even though there are 3 constructors for FragmentStateAdapter including one that takes a FragmentActivity, the constructor of your FragmentStateAdpter should inherit from is FragmentStateAdapter(FragmentManager fragmentManager, AndroidX.Lifecycle.Lifecycle lifecycle)
Because FragmentStateAdapter is an abstract class you then just need to override both ItemCount and CreateFragment.
The code snippet below is an example of how you implement them.
public class MonitorsViewPagerFragmentAdapter : FragmentStateAdapter
private readonly int itemCount;
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,
And an example of calling it from the fragment that is using the FragmentStateAdapter
monitorsViewPagerFragmentAdapter = new MonitorsViewPagerFragmentAdapter(ChildFragmentManager, ViewLifecycleOwner.Lifecycle, 3);