Aggiungi e rimuovi dinamicamente le schede in TabLayout(material design) Android




material design 2 tabs (2)

Ho un TabLayout e dentro che ho ViewPager. Devo aggiungere e rimuovere dinamicamente la scheda in tablayout (material design). Posso aggiungere le schede in modo dinamico ma rimuovendo la scheda, la scheda viene rimossa correttamente. Ma l'ultimo elemento di viewpager è stato cancellato. Quindi la scheda non mostra il frammento specifico. Per tua informazione ho usato FragmentPagerAdapter.

Ho seguito questo tutorial per implementarlo

https://androidbelieve.com/navigation-drawer-with-swipe-tabs-using-design-support-library

public class TabFragment extends Fragment {

    public static TabLayout tabLayout;
    public static ViewPager viewPager;
    public static int int_items = 2;
    private MyNewsFragment mMyNewsFragment;
    private ArrayList<TabFragmentModelClass> mFragmentArrayList;
    private TabLayoutAdapter mTabLayoutAdapter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        mMyNewsFragment = new MyNewsFragment();
        /**
         *Inflate tab_layout and setup Views.i;;a
         */
        View x = inflater.inflate(R.layout.tab_layout, null);
        tabLayout = (TabLayout) x.findViewById(R.id.tabs);
        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);  // scorllable tab
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);  // tab name fill parent
        viewPager = (ViewPager) x.findViewById(R.id.viewpager);
        mFragmentArrayList = new ArrayList<>();
        mFragmentArrayList.add(new TabFragmentModelClass(new MyNewsSelectionFragment(), "", ""));
        mFragmentArrayList.add(new TabFragmentModelClass(mMyNewsFragment, "", getResources().getString(R.string.mynews)));
        mFragmentArrayList.add(new TabFragmentModelClass(new BreakingNewsFragment(), "", getResources().getString(R.string.breakingnews)));

        // Selected news from shared preference
        ArrayList<MyNewsSharedPreferenceModelClass> tempSharedPreferenceModelClass = new MyNewsSharedPreferenceClass().loadFavorites(getActivity());
        for (int i = 0; i < tempSharedPreferenceModelClass.size(); i++) {
            mFragmentArrayList.add(new TabFragmentModelClass(new CategoreyNewsFragment(tempSharedPreferenceModelClass.get(i).getmCatID()), tempSharedPreferenceModelClass.get(i).getmCatID(),
                    tempSharedPreferenceModelClass.get(i).getmCatName()));
        }


 }


        /**
         *Set an Apater for the View Pager
         */
        mTabLayoutAdapter = new TabLayoutAdapter(getChildFragmentManager(), mFragmentArrayList);
        viewPager.setAdapter(mTabLayoutAdapter);
        viewPager.setOffscreenPageLimit(mFragmentArrayList.size());
        tabLayout.setupWithViewPager(viewPager);


        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                tabLayout.getTabAt(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (state == 1) {
                    updateMyNewsFragment();
                }
            }
        });

        /**
         * Now , this is a workaround ,
         * The setupWithViewPager dose't works without the runnable .
         * Maybe a Support Library Bug .
         */

        tabLayout.post(new Runnable() {
            @Override
            public void run() {

                tabLayout.getTabAt(0).setIcon(R.mipmap.mynewselection);

                tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                    @Override
                    public void onTabSelected(TabLayout.Tab tab) {
                        viewPager.setCurrentItem(tab.getPosition());
                        switch (tab.getPosition()) {
                            case 1:

                                System.out.println("000000000000000000000 ");
                                updateMyNewsFragment();
                                break;
                        }
                    }

                    @Override
                    public void onTabUnselected(TabLayout.Tab tab) {
                    }


                    @Override
                    public void onTabReselected(TabLayout.Tab tab) {
                    }
                });

            }
        });
        return x;
    }

    /**
     * update the mynews selection
     * this method trigger from the MainNewsActivity
     */
    public void updateMyNewsFragment() {
        if (ApplicationController.getInstance().getBoolPref(CommonVariableInterFace.isNewsSelected)) {
            mMyNewsFragment.sendMyNewsRequest();
            ApplicationController.getInstance().setBoolPref(CommonVariableInterFace.isNewsSelected, false);
        }
    }

    /**
     * update the tab values
     * this method trigger from the MainNewsActivity
     * if value is zero need to add in tab
     * if value is one need to remove in tab
     */
    public void updateTabvalue(String catId, String catName, int value) {

            if (value == 0) { // add the value in tab

                mFragmentArrayList.add(new TabFragmentModelClass(new CategoreyNewsFragment(catId), catId,
                        catName));
            }  else {      // Removing the tab
                for (int i = 0; i < mFragmentArrayList.size(); i++) {
                    if (mFragmentArrayList.get(i).getmCatID().equalsIgnoreCase(catId)) {

                        Log.i("-----same id ", catId);
                        mFragmentArrayList.remove(i);
                        mTabLayoutAdapter = new TabLayoutAdapter(getChildFragmentManager(), mFragmentArrayList);
                        viewPager.setAdapter(mTabLayoutAdapter);
                    }
                }
            }

            mTabLayoutAdapter.notifyDataSetChanged();
            viewPager.setOffscreenPageLimit(mFragmentArrayList.size());
            tabLayout.getTabAt(0).setIcon(R.mipmap.mynewselection);
             tabLayout.setupWithViewPager(viewPager);


            tabLayout.post(new Runnable() {
                @Override
                public void run() {

                    tabLayout.getTabAt(0).setIcon(R.mipmap.mynewselection);

                    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                        @Override
                        public void onTabSelected(TabLayout.Tab tab) {
                            viewPager.setCurrentItem(tab.getPosition());
                            switch (tab.getPosition()) {
                                case 1:
                                    updateMyNewsFragment();
                                    break;
                            }
                        }

                        @Override
                        public void onTabUnselected(TabLayout.Tab tab) {
                        }


                        @Override
                        public void onTabReselected(TabLayout.Tab tab) {
                        }
                    });

                }
            });
    }

    public void openSpecificTab() {

//        tabLayout.settab
//        tabLayout.se
    }
}

Codice dell'adattatore:

public class TabLayoutAdapter extends FragmentPagerAdapter {

    private long baseId = 0;
    ArrayList<TabFragmentModelClass> fragmentAdapterArrayList;

    public TabLayoutAdapter(FragmentManager fm, ArrayList<TabFragmentModelClass> fragmentArrayList) {
        super(fm);
        fragmentAdapterArrayList = fragmentArrayList;
    }

    @Override
    public Fragment getItem(int position) {

        if (position == 0)
            return fragmentAdapterArrayList.get(position).getmFragment();
        if (position == 1)
            return fragmentAdapterArrayList.get(position).getmFragment();
        if (position == 2)
            return fragmentAdapterArrayList.get(position).getmFragment();

        return new CategoreyNewsFragment().newInstance(fragmentAdapterArrayList.get(position).getmCatID());
    }

    @Override
    public int getCount() {
        return fragmentAdapterArrayList.size();
    }


    //this is called when notifyDataSetChanged() is called
    @Override
    public int getItemPosition(Object object) {
        // refresh all fragments when data set changed
        return TabLayoutAdapter.POSITION_NONE;
    }


    @Override
    public long getItemId(int position) {
        // give an ID different from position when position has been changed
        return baseId + position;
    }

    /**
     * Notify that the position of a fragment has been changed.
     * Create a new ID for each position to force recreation of the fragment
     *
     * @param n number of items which have been changed
     */
    public void notifyChangeInPosition(int n) {
        // shift the ID returned by getItemId outside the range of all previous fragments
        baseId += getCount() + n;
    }

    /**
     * //     * This method returns the title of the tab according to the position.
     * //
     */

    @Override
    public CharSequence getPageTitle(int position) {
        return fragmentAdapterArrayList.get(position).getmCatName();
    }
}

Rimuovi la scheda da TabLayout

...
public void removeTab(int position) {
    if (mTabLayout.getTabCount() >= 1 && position<mTabLayout.getTabCount()) {
          mTabLayout.removeTabAt(position);
          mPagerAdapter.removeTabPage(position);
    }
}
...

Aggiungi un metodo removeTabPage al tuo PagerAdapter

...
public void removeTabPage(int position) {
    if (!tabItems.isEmpty() && position<tabItems.size()) {
          tabItems.remove(position);
          notifyDataSetChanged();
    }
}
...

Aggiungi una Tab

...
private void addTab(String title) {
        mTabLayout.addTab(mTabLayout.newTab().setText(title));
        mPagerAdapter.addTabPage(title);
}
...

Aggiungi un metodo addTabPage al tuo PagerAdapter

...
public void addTabPage(String title) {
      tabItems.add(title);
      notifyDataSetChanged();
}
...

Guarda questo esempio di codice per un esempio completo: ...samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutUsage.java


Con la nuova libreria di supporto (sto usando 23.2.1) dovresti solo aggiungere al Viewpager e non al TabLayout (altrimenti finirai con le doppie schede e altri comportamenti funky). Quindi, per aggiornare la risposta di TouchBoarder :

Aggiungi un metodo removeTabPage al tuo PagerAdapter

public void removeTabPage(int position) {
    if (!tabItems.isEmpty() && position<tabItems.size()) {
          tabItems.remove(position);
          notifyDataSetChanged();
    }
}

Aggiungi un metodo addTabPage al tuo PagerAdapter

public void addTabPage(String title) {
      tabItems.add(title);
      notifyDataSetChanged();
}




android-tablayout