Question

Je suis en utilisant le code que j'ai trouvé ici.

public class ActionBarTabs extends SherlockFragmentActivity {
CustomViewPager mViewPager;
TabsAdapter mTabsAdapter;
TextView tabCenter;
TextView tabText;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    mViewPager = new CustomViewPager(this);
    mViewPager.setId(R.id.pager);

    setContentView(mViewPager);
    ActionBar bar = getSupportActionBar();
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

    mTabsAdapter = new TabsAdapter(this, mViewPager);

    mTabsAdapter.addTab(bar.newTab().setText("Home"),
            ToolKitFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText("FujiSan"),
            FujiFragment.class, null);
}

public static class TabsAdapter extends FragmentPagerAdapter implements
        ActionBar.TabListener, ViewPager.OnPageChangeListener {
    private final Context mContext;
    private final ActionBar mActionBar;
    private final ViewPager mViewPager;
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

    static final class TabInfo {
        private final Class<?> clss;
        private final Bundle args;

        TabInfo(Class<?> _class, Bundle _args) {
            clss = _class;
            args = _args;
        }
    }

    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mActionBar = activity.getSupportActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
        TabInfo info = new TabInfo(clss, args);
        tab.setTag(info);
        tab.setTabListener(this);
        mTabs.add(info);
        mActionBar.addTab(tab);
        notifyDataSetChanged();
    }

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

    @Override
    public Fragment getItem(int position) {
        TabInfo info = mTabs.get(position);
        return Fragment.instantiate(mContext, info.clss.getName(),
                info.args);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset,
            int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        mActionBar.setSelectedNavigationItem(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        Object tag = tab.getTag();
        for (int i = 0; i < mTabs.size(); i++) {
            if (mTabs.get(i) == tag) {
                mViewPager.setCurrentItem(i);
            }
        }
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
}
}

Je suis en train de le modifier, de sorte que je peux supprimer les onglets de façon dynamique.J'ai essayé par tout simplement la création de cette fonction:

    public void removeTab(ActionBar.Tab tab) {
        mTabs.remove(tab);
        mActionBar.removeTab(tab);
        notifyDataSetChanged();
    }

Mais j'obtiens toujours un indexoutofboundsexception.Quelqu'un sait-il une bonne façon de le faire?

MODIFIER

En changeant ma méthode:

    public void removeTab(ActionBar.Tab tab) {
        mTabs.remove(tab.getTag());
        mActionBar.removeTab(tab);
        notifyDataSetChanged();
    }

J'ai pu réussir à supprimer des onglets.Cependant, quand je supprime un onglet qui n'EST PAS celle de l'extrême droite, la vue (ou fragment?) qui a été associée à l'onglet ne va pas loin.Au lieu de cela, il semble être associée avec le deuxième plus haut de l'onglet.Par exemple, si j'ai supprimé l'onglet 0, tab 0 de vue se déplace vers l'onglet 1.Si je supprime l'onglet avec les ID les plus élevés puis sur l'onglet et afficher en aller correctement, mais ensuite, revenez quand j'ajoute un nouvel onglet.

C'est comme si il y a une liste de fragments de quelque part qui est associé avec les onglets et la suppression de l'onglet ne pas supprimer le fragment.Quelqu'un aurait-il une idée de ce qui cause cela?

EDIT2

J'ai essayé de supprimer les fragments avec:

            Fragment fragmentToRemove = getItem(tab.getPosition());
            destroyItem(mViewPager, tab.getPosition(), fragmentToRemove);

et aussi

        Fragment fragmentToRemove = getItem(tab.getPosition());
        FragmentTransaction fragmentTransaction = mActivity
                .getSupportFragmentManager().beginTransaction();
        fragmentTransaction.remove(fragmentToRemove);
        fragmentTransaction.commit();

Mais aucune n'a fonctionné jusqu'ici.

Était-ce utile?

La solution

obtenu!

public void removeTab(ActionBar.Tab tab) {
    mTabs.remove(tab.getTag());
    mActionBar.removeTab(tab);
    notifyDataSetChanged();
}

et remplacement destructitem

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // TODO Auto-generated method stub
        super.destroyItem(container, position, object);
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

fonctionne parfaitement !!!

Autres conseils

Je viens de découvrir aujourd'hui que le vrai truc à soutenir l'insertion ou la suppression des onglets est à remplacer FragmentPagerAdapter.getItemPosition():

@Override
public int getItemPosition(Object object) {
    Fragment fragment = (Fragment) object;
    for (int i = 0; i < tabInfos.size(); i++) {
        if (tabInfos.get(i).clss == fragment.getClass()) {
            return i;
        }
    }
    // The tab must have been removed
    return POSITION_NONE;
}

getItemPosition() sera appelé par le ViewPager après avoir appelé notifyDataSetChanged() (après l'ajout/la suppression des tabulations).L' ViewPager essaie de resynchroniser son cache avec cet adaptateur.Il appelle getItemPosition() pour chaque "objet" (Fragment) qu'il détient, et nous dire quelle est la position de ce Fragment est de.Si aucune correspondance n'est trouvée, c'est parce que nous avons supprimé cet onglet, donc retour POSITION_NONE.

J'ai aussi trouvé qu'il est important de remplacer FragmentPagerAdapter.getItemId() si vous insérez ou supprimer des onglets, parce que les Fragments seront changements de positions de gauche et de droite.Cette méthode est appelée par FragmentPagerAdapter.instantiateItem() et est ajouté à un nom (Chaîne de caractères) pour l'élément.Il utilise ce nom pour rechercher une pré-existant Fragment avec un nom correspondant (si il y en a un) sinon instancier un nouveau.Voici un code:

@Override
public long getItemId(int position) {
    TabInfo info = tabInfos.get(position);
    // The default hashCode() implementation is based on memory address, which will be unique
    int hash = info.clss.hashCode();
    return hash;
}

OK - Celui-ci a mangé mon déjeuner pendant 2 semaines.Je n'ai pas trouvé que ce qui précède a travaillé pour moi du tout comme indiqué.J'utilise Android Studio 3.5.1 au cas où cela importe.

Que suit est mon code de fragmentpageradapter dans son intégralité.Il contient la plupart de tout ce dont vous devriez avoir besoin.Le code de fragment est assez simple pour que chacun de vos fragments contienne.Mais laissez-moi savoir si plus est requis ou si vous avez des questions.

En outre, si vous avez des commentaires ou trouvez des erreurs, veuillez poster un commentaire.J'espère que cela aide les autres.

import android.content.Context;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.tabs.TabLayout;

import java.util.ArrayList;

public class ChecklistPagerAdapter extends FragmentPagerAdapter {

    private final Context mContext;
    private int currentTabPosition = -1;
    ArrayList<String> tabNames = new ArrayList<>();
    ArrayList<Fragment> fragments = new ArrayList<>();

    public ChecklistPagerAdapter(Context context, FragmentManager fm) {
        super(fm);
        mContext = context;
    }

    public void add(Fragment fragment, String title) {
        tabNames.add(title);
        fragments.add(fragment);
    }

    public int getCurrentTabPosition() {
        return currentTabPosition;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getItemPosition(@NonNull Object object) {
        ChecklistFragment fragment = (ChecklistFragment) object;
        for (int i = 0; i < fragments.size(); i++) {
            if (fragments.get(i).equals(fragment)) {
                return i;
            }
        }
        return POSITION_NONE;
    }

    @Override
    public long getItemId(int position) {
        return fragments.get(position).hashCode();
    }

    @Override
    public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        super.setPrimaryItem(container, position, object);
        currentTabPosition = position;
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return tabNames.get(position);
    }

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

    public void removeTab(TabLayout tabLayout, ViewPager viewPager, DBHelper dbHelper) {
        // Get current tab position as it changes below
        int position = currentTabPosition;

        // Get current fragment representing curTab
        ChecklistFragment fragment = (ChecklistFragment) fragments.get(position);

        // Remove Tab
        tabLayout.removeTabAt(position);

        // Remove from ArrayLists
        fragments.remove(position);
        tabNames.remove(position);

        // Remove fragment
        FragmentManager fragmentManager = fragment.getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.remove(fragment);
        fragmentTransaction.commit();

        // Refresh
        tabLayout.invalidate();
        notifyDataSetChanged();

        // Remove all records from ChecklistTab table
        dbHelper.clearChecklistTab(fragment.getOutingId(), fragment.getChecklistId());
    }
}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top