-1


Need a help with dynamic ViewPager with EditText (straggling to do a multiple tabbed editor).
Here are problems I faced:

  • e. g. I create 3 pages and put some text, so I have
    page0 - "a"
    page1 - "b"
    page2 - "c"
    Adding works normally here, removing page0 leads not to "a" "c" but to "a" "b" left, removing page0 leads to "a" "b" instead of "b" "c" as well, removing page2 is ok. So it seems like pager remembers text of removed page n and moves it to page n+1, text from page n+1 to n+2 and so on
  • same pages with the same text, but now I remove page1 and page2 (the order doesn't matter) so text "a" left. Adding two new pages will recreate "b" and "c", next pages would be blank as they should be.
    if I remove just page1 and add new page, text "c" will appear.

I've been here, here and here, no help. Tried to follow getItem(int position) calls
Also searched ViewPager and FragmentStatePagerAdapter sources, it looks like it has smth to do with instantiateItem and/or destroyItem but I have no clue what exactly.


Here is my code:

Adapter

public class PagerAdapter extends FragmentStatePagerAdapter {
        private ArrayList<Fragment> fragmentsList = new ArrayList<>();
        private ArrayList<String> titlesList = new ArrayList<>();
        private TabLayout layout;
        public PagerAdapter(FragmentManager manager, Context context, ViewPager pager, TabLayout layout) {
            super(manager);
            this.layout = layout;
        }
        @Override
        public Fragment getItem(int position) {
            return fragmentsList.get(position);
        }
        @Override
        public int getItemPosition(@NonNull Object object) {
            return POSITION_NONE;
        }    
        @Override
        public int getCount() {
            return fragmentsList.size();
            }
        @Override
        public CharSequence getPageTitle(int position) {
            return titlesList.get(position);
        }

        public void addFrag(Fragment f, String s) {
            fragmentsList.add(f);
            titlesList.add(s);
        }

        public void removeFragment(int position) {
            if (layout.getChildCount() > 0) 
                layout.removeTabAt(position);
            Fragment fragment = fragmentsList.get(position);
            fragmentsList.remove(fragment);
            titlesList.remove(position);
            FragmentManager manager = fragment.getFragmentManager();
            FragmentTransaction trans = manager.beginTransaction();
            trans.remove(fragment);
            trans.commit();
            notifyDataSetChanged();
        }
    }

RootFragment

 public class RootFragment extends Fragment {
        private TabLayout layout;
        private ViewPager pager;
        private PagerAdapter adapter;
        private int currentTab;
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View view = inflater.inflate(R.layout.root_fragment, container, false);

            pager = view.findViewById(R.id.viewpager);
            layout = view.findViewById(R.id.sliding_tabs);
            adapter = new PagerAdapter(getFragmentManager(), getActivity(), pager, layout);
            pager.setAdapter(adapter);
            layout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
                    currentTab = tab.getPosition();
                    pager.setCurrentItem(currentTab);
                }
                @Override
                public void onTabUnselected(TabLayout.Tab tab) {
                }
                @Override
                public void onTabReselected(TabLayout.Tab tab) {
                }
            });

            return view;
        }

        public void addTab(String title) {
            Bundle bundle = new Bundle();
            bundle.putString("data", title);
            LeafFragment leafFragment = new LeafFragment();
            leafFragment.setArguments(bundle);
            adapter.addFrag(leafFragment, title);
            adapter.notifyDataSetChanged();
            layout.setupWithViewPager(pager);
            currentTab = adapter.getCount() - 1;
            pager.setCurrentItem(currentTab);
        }

        public void deleteTab(int position) {
            adapter.removeFragment(position);
        }
    }

Thanks and sorry for my English.

1 Answers1

1

FragmentStatePagerAdapter already stores a list of Fragments, you don't need (and potentially, you should not) implement your own list while using it. Simply:

public class MyAdapter extends FragmentStatePagerAdapter {
    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public Fragment getItem(int position) {
       //Simply create a fragment based on position here
    }
}

Second, the unfortunate truth is, removing/reordering fragments in a FragmentStatePagerAdapter appears to have still open bugs as here:

https://issuetracker.google.com/issues/36956111

My suggestion is to simply re-create the adapter if you need to delete fragments from the adapter.

breakline
  • 5,776
  • 8
  • 45
  • 84