Frage

Ich verwende Code, den ich gefunden habe hier.

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) {
    }
}
}

Ich versuche es so zu ändern, dass ich Registerkarten dynamisch löschen kann.Ich habe es versucht, indem ich einfach diese Funktion erstellt habe:

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

Aber ich bekomme immer eine indexoutofboundsexception.Kennt jemand einen guten Weg, dies zu tun?

BEARBEITEN

Indem ich meine Methode ändere in:

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

Ich konnte Tabs erfolgreich entfernen.Wenn ich jedoch eine Registerkarte lösche, die NICHT die ganz rechts ist, wird die Ansicht (oder das Fragment?), das mit dem Tab verknüpft war, verschwindet nicht.Stattdessen scheint es mit der nächsthöheren Registerkarte verknüpft zu werden.Wenn ich beispielsweise Tab 0 gelöscht habe, wird die Ansicht von Tab 0 nur zu Tab 1 verschoben.Wenn ich den Tab mit der höchsten ID lösche, verschwinden der Tab und die Ansicht korrekt, kommen aber wieder, wenn ich einen neuen Tab hinzufüge.

Es ist, als ob irgendwo eine Liste von Fragmenten vorhanden wäre, die den Registerkarten zugeordnet sind, und das Löschen der Registerkarte löscht das Fragment nicht.Hat jemand eine Idee, was das verursacht?

BEARBEITUNG2

Ich habe versucht, die Fragmente mit zu löschen:

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

und auch

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

Aber beides hat bisher nicht funktioniert.

War es hilfreich?

Lösung

hat es bekommen! generasacodicetagpre.

und überschreiben destroyitem generasacodicetagpre.

funktioniert perfekt !!!

Andere Tipps

Ich habe gerade heute entdeckt, dass der wahre Trick beim Einfügen oder Entfernen von Tabs darin besteht, sie zu überschreiben 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() wird von der aufgerufen ViewPager nachdem Sie angerufen haben notifyDataSetChanged() (nach dem Hinzufügen / Entfernen von Registerkarten).Der ViewPager versucht, seinen Cache mit diesem Adapter neu zu synchronisieren.Es ruft getItemPosition() für jedes 'Objekt' (Fragment), das es enthält, und wir sagen ihm, von welcher Position dieses Fragment stammt.Wenn es keine Übereinstimmung gibt, liegt es daran, dass wir diesen Tab gelöscht haben, also kehren Sie zurück POSITION_NONE.

Ich habe auch festgestellt, dass es wichtig ist, zu überschreiben FragmentPagerAdapter.getItemId() wenn Sie Registerkarten einfügen oder entfernen, weil die Fragmente die Positionen nach links und rechts verschieben.Diese Methode wird aufgerufen von FragmentPagerAdapter.instantiateItem() und wird an einen Namen (String) für das Element angehängt.Es verwendet diesen Namen, um ein bereits vorhandenes Fragment mit einem übereinstimmenden Namen (falls vorhanden) zu suchen, andernfalls wird ein neues instanziiert.Hier ist ein 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 - das aß mein Mittagessen für 2 Wochen.Ich habe nicht gefunden, dass das oben genannte oben genau wie gezeigt für mich funktionierte.Ich verwende Android Studio 3.5.1, falls dies ankommt.

Was folgt, ist mein FragmentPagerAdapter-Code in seiner Gesamtheit.Es enthält am meisten alles, was Sie brauchen sollten.Der Fragmentcode ist für unabhängig von jedem Ihrer Fragmente ziemlich unkompliziert.Aber lassen Sie mich wissen, ob mehr benötigt wird oder wenn Sie Fragen haben.

Wenn Sie auch Kommentare haben oder Fehlern finden, posten Sie bitte einen Kommentar.Ich hoffe, das hilft anderen. generasacodicetagpre.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top