5

Tôi đang sử dụng mã tôi đã tìm thấy here.Làm cách nào để xóa tab có thanh tác vụ, chế độ xem và nhiều đoạn?

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

Tôi đang cố sửa đổi để tôi có thể xóa các tab động. Tôi đã thử bằng cách đơn giản tạo chức năng này:

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

Nhưng tôi luôn nhận được quan điểm về giới tính. Có ai biết một cách tốt để làm điều này?

EDIT

Bằng cách thay đổi phương pháp của tôi để:

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

tôi đã có thể thành công loại bỏ các tab. Tuy nhiên, khi tôi xóa một tab KHÔNG PHẢI là tab ở bên phải, chế độ xem (hoặc đoạn?) Được liên kết với tab sẽ không biến mất. Thay vào đó, nó dường như được kết hợp với tab cao nhất tiếp theo. Ví dụ, nếu tôi đã xóa tab 0, tab 0's view chỉ di chuyển đến tab 1. Nếu tôi xóa tab có ID cao nhất thì tab và chế độ xem sẽ biến mất một cách chính xác nhưng sau đó, hãy BẬT lại khi tôi thêm tab mới.

Dường như có danh sách các đoạn ở đâu đó đang được liên kết với các tab và xóa tab sẽ không xóa đoạn. Có ai có bất cứ ý tưởng gì gây ra điều này?

EDIT2

Tôi đã cố gắng để xóa các mảnh vỡ với:

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

và cũng

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

Nhưng không phải đã làm việc cho đến nay.

Trả lời

8

OK!

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

và ghi đè 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(); 
    } 

trình một cách hoàn hảo !!!

4

Tôi chỉ phát hiện ra ngày hôm nay rằng các trick thực để hỗ trợ chèn hoặc xóa tab là để ghi đè 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() sẽ được gọi bởi các ViewPager sau khi bạn đã gọi notifyDataSetChanged() (sau khi thêm/gỡ bỏ các tab). ViewPager đang cố gắng đồng bộ hóa bộ nhớ cache với bộ điều hợp này. Nó gọi là getItemPosition() cho mỗi 'đối tượng' (Fragment) mà nó nắm giữ, và chúng ta nói cho nó biết vị trí của Fragment. Nếu không có kết quả phù hợp, đó là vì chúng tôi đã xóa tab đó, vì vậy hãy trả lại POSITION_NONE.

Tôi cũng thấy rằng điều quan trọng là ghi đè FragmentPagerAdapter.getItemId() nếu bạn chèn hoặc xóa tab, vì Phân đoạn sẽ chuyển vị trí sang trái và sang phải. Phương thức này được gọi bởi FragmentPagerAdapter.instantiateItem() và được nối thêm vào tên (Chuỗi) cho mục đó. Nó sử dụng tên này để tra cứu một Fragment đã tồn tại trước đó với một tên phù hợp (nếu có), nếu không thì sẽ tạo ra một cái mới.Dưới đây là một số mã:

@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

Cảm ơn. Bạn có thể chia sẻ kết quả của việc không thực hiện hai lần ghi đè này không? Đó có phải là một điều hiệu suất, hoặc nó sẽ dẫn đến hành vi không chính xác? – JRun

+0

Tôi hiểu ý tưởng để ghi đè các chức năng này, ... nhưng cuộc gọi thực sự xóa tab từ ViewPager là gì? – gcl1

+0

Tôi muốn giải quyết câu hỏi trên với @ jfritz42. Cảm ơn. – gcl1