androidandroid-viewpagerandroid-pageradapter

PagerAdapter.notifyDataSetChanged does not refresh fragments


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):

So 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


Solution

  • I know this question is a bit old, but it might be interesting to know that Google recently solved this problem with ViewPager2. See examples here

    First of all, a the following dependency in your build.gradle file :

      dependencies {
         implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
      }
    

    Now you can replace your ViewPager in your xml file with :

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    

    Then you will need to replace ViewPager by ViewPager2 in your activity

    ViewPager2 needs either a RecycleView.Adapter, or a FragmentStateAdapter :

        public class TabAdapter extends FragmentStateAdapter {
            private final List<Tab> tabs;
    
            public TabAdapter(@NonNull FragmentManager fm, List<Tab> tabs, Lifecycle lifecycle) {
                super(fm, lifecycle);
    
                this.tabs = tabs;
            }
    
            @NonNull
            @Override
            public Fragment createFragment(int position) {
                //create your fragment here
            }
    
            @Override
            public int getItemCount() {
                return tabs.size();
            }
    
            @Override
            public long getItemId(int position) {
                // use a distinct id for each item to allow the adapter to see the changes
            }
        }
    

    In the case you were using a TabLayout, you can use a TabLayoutMediator :

            TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager, true, new TabLayoutMediator.OnConfigureTabCallback() {
                @Override
                public void onConfigureTab(@NotNull TabLayout.Tab tab, int position) {
                    // configure your tab here
                    tab.setText(tabs.get(position).getTitle());
                }
            });
    
            tabLayoutMediator.attach();
    

    In order to remove data, after removing the item from your collection you can either call the notifyDataSetChanged() method or more specifically the notifyItemRemoved() with the position of removed item