5

Używam kodu Znalazłem here.Jak usunąć kartę z paskiem akcji, stronami podglądu i wieloma fragmentami?

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

Próbuję go zmodyfikować, aby móc dynamicznie usuwać karty. Próbowałem po prostu tworząc tę ​​funkcję:

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

Ale zawsze otrzymuję indeks wyjątkowego związku. Czy ktoś wie, jak to zrobić?

EDIT

Zmieniając moją metodę:

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

byłem w stanie skutecznie usunąć karty. Jednak po usunięciu karty, która NIE jest tą z prawej strony, widok (lub fragment?) Powiązany z kartą nie zniknie. Zamiast tego wydaje się, że jest powiązany z kolejną najwyższą kartą. Na przykład, jeśli usunąłem kartę 0, widok zakładki 0 przesunie się do zakładki 1. Jeśli usuniemy kartę z najwyższym identyfikatorem, karta i widok znikną poprawnie, ale potem COME BACK po dodaniu nowej karty.

To tak, jakby była lista fragmentów gdzieś powiązanych z zakładkami, a usunięcie karty nie powoduje usunięcia fragmentu. Czy ktoś ma pojęcie, co to powoduje?

EDIT2

Próbowałem usunąć fragmenty z:

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

a także

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

Ale nie pracował do tej pory.

Odpowiedz

8

Gotowy!

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

i zastąpić destroyItem

@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(); 
    } 

działa idealnie !!!

4

Właśnie odkryłem dzisiaj, że prawdziwe trick wspieranie wkładania lub wyjmowania kart ma zastąpić 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() zostanie wywołana przez ViewPager po nazwali notifyDataSetChanged() (po dodaniu/zaczepy usuwanie). Urządzenie ViewPager próbuje ponownie zsynchronizować pamięć podręczną z tym adapterem. Wywołuje on getItemPosition() dla każdego "obiektu" (Fragmentu), który posiada, i mówimy, z której pozycji pochodzi Fragment. Jeśli nie ma dopasowania, dzieje się tak, ponieważ usunęliśmy tę kartę, więc zwróć POSITION_NONE.

Zauważyłem również, że ważne jest zastąpienie FragmentPagerAdapter.getItemId(), jeśli wstawisz lub usuniesz zakładki, ponieważ Fragmenty będą przesuwać pozycje w lewo i w prawo. Ta metoda jest wywoływana przez FragmentPagerAdapter.instantiateItem() i jest dołączana do nazwy (String) dla elementu. Używa tej nazwy do wyszukania istniejącego Fragmentu o pasującej nazwie (jeśli jest taka), w przeciwnym razie utworzyć nowy.Oto kod:

@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; 
} 
+0

Dzięki. Czy możesz podzielić się rezultatami braku implementacji tych dwóch nadpisań? Czy jest to działanie, czy może spowodować nieprawidłowe zachowanie? – JRun

+0

Rozumiem pomysł, aby zastąpić te funkcje, ... ale jaki jest powód, aby faktycznie usunąć zakładkę z ViewPager? – gcl1

+0

Chciałem rozwiązać powyższe pytanie do @ jfritz42. Dzięki. – gcl1

Powiązane problemy