My Activity
contains a ViewPager
and it's custom Adapter
which extends FragmentStatePagerAdapter
. ViewPager
contains 3 fragments
Code to remove Fragments from the ViewPager
MainActivity
public void deleteElement(){
final int currentItem = mViewPager.getCurrentItem();
mPagerAdapter.removeItem(currentItem);
mPagerAdapter.notifyDataSetChanged();
}
CustomPagerAdapter
private ArrayList<Item> data;
public void removeItem(int index){
data.remove(index);
}
when removing the middle Fragment
(index 1):
data
i'm removing the correct item
. Fragment
3 is removed after notifyDataSetChanged
and the current Fragment
is still the fragment that the user saw and the data that is being loaded is from the SavedInstance
bundleSo the end result that the user still see the same Fragment
that he tried to remove which is kinda suck for him.
Ideas?
***** EDIT ******
seems like ViewPager2 Features might solve this issue and many other issues as well
You can use startActivityForResult(or broadcast/receiver) to get the result from the activity. Then use adapter. notifyDataSetChanged to refresh the fragment.
As we already know that ViewPager2 is built on RecyclerView that's why it's easy to update only one item by calling the method notifyItemChanged(index). If we want to update all items then we can also do this by simply calling the notifyDatasetChanged() method. That's it for now.
The difference is that you can use Fragments inside a FragmentPageAdapter . If you want to have fragments that are going to be used in other parts of your code this is your Adapter. Otherwise if you only want to have code that isn't going to be reused, you can use PagerAdapter .
ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .
Try adding this:
private class MyPagerAdapter extends FragmentStatePagerAdapter {
//... your existing code
@Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
}
You have no choice but to implement PagerAdapter#getItemPosition
. Looking at the source that's exactly how ViewPager determines how to update its position, add new fragments or drop dead ones after notifyDataSetChanged
. It shouldn't be too hard, you just need to access the state of the passed fragment, and you also need to access the master state in your activity which holds your ordering.
It's also required you implement getItemId
to return a consistent ID for each fragment, because they can be reordered.
This is how I handled it in a ViewPager of photos.
private inner class PhotoPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int): PhotoViewFragment {
// getItem is called to instantiate the fragment for the given page.
return PhotoViewFragment.newInstance(position, [email protected][position])
}
override fun getItemId(position: Int): Long {
return [email protected][position].ID!!.hashCode().toLong()
}
override fun getItemPosition(`object`: Any): Int {
val frag = `object` as PhotoViewFragment
val idx = [email protected] { ph -> ph.ID == frag.dataBinding.photo.ID }
return if (idx >= 0) idx else PagerAdapter.POSITION_NONE
}
override fun getCount(): Int {
return [email protected]
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With