2012-09-07 48 views
10

我使用的ViewpagerFragmentPagerAdapter允許添加和刪除頁面。每個頁面顯示從互聯網獲得的數據。Viewpager和FragmentPagerAdapter:頁面視圖刪除

隨着新頁面的添加,新的Fragment與該頁面相關聯。數據通過AsyncTask獲取並顯示在Fragment中。當用戶選擇刪除一個頁面時,這個想法是銷燬該頁面和相關的片段。

總的來說,這一切都很好。我看到的問題如下:

  1. 您有三個頁面的數據:

    [第1頁] [第2頁] [第3頁]

  2. 你刪除任何除最後一頁以外的頁面,比如第2頁;頁2按需要消失:

    [1] [第3頁]

  3. 您添加新的頁面;但不是空白的新頁面,新頁面顯示的是第3頁的數據(視圖)。

    [Page 1] [第3頁] [第4頁,但顯示第3頁的視圖/數據應爲空白]


在我的活動頁面移除代碼如下:

// Destroy fragment for this page 
    DataListFragment curFrag = getFragmentByName(currentPage); 
    FragmentManager fm = getSupportFragmentManager(); 
    fm.beginTransaction().remove(curFrag).commit(); 
    fm.executePendingTransactions(); 
    curFrag = null; 

    // Remove page and update adapter 
    mPageTitles.remove(position);   
    mAdapter.notifyDataSetChanged(); 

使用調試器,則說明該片段從FragmentManager刪除撥打executePendingTransactions()後。但在FrampePagerAdapters調用mAdapter.notifyDataSetChanged()中,片段被添加回來,然後在創建新頁面時顯示。

我試過使用FrameStatePagerAdapter,因爲那應該允許銷燬碎片​​,但它不起作用。在我的FragmentPagerAdapter的getItemPosition()方法中,我使用return FragmentAdapter.POSITION_NONE;,正如在我遇到的另一篇SO文章中指出的那樣。

看起來好像該頁面的視圖沒有被銷燬,但後來又被添加回新頁面。我試圖在新頁面的視圖上使用removeViewAt()方法,但這並不奏效。


作爲新來這個,我敢肯定,我失去了一些東西明顯...

+0

我不知道它的東西很明顯。我也遇到這個問題。你解決了嗎?這裏可能有一個答案:http://stackoverflow.com/questions/12510404/reorder-pages-in-fragmentstatepageradapter-using-getitempositionobject-object –

+1

你可以告訴我們你的覆蓋方法:public Fragment getItem(int position) – Gomino

+0

When你正在刪除一個片段,你不會從適配器中刪除它。這就是它再次出現的原因。您需要將它從適配器中刪除(不是查看,而是在getItem()方法中使用的Item)。第四個片段看起來像第三個,因爲它重用了片段,就像ListView的適配器一樣。適配器邏輯中有錯誤。顯示你的適配器類 –

回答

1

你還是擴展FragmentStatePagerAdapter並刪除該適配器的項目列表中選擇相應的項目,而不是試圖從活動中刪除片段。刪除適配器中的項目後,請勿忘記撥打adapter.notifyDataSetChanged()。一旦完成,ViewPagerFragmentStatePagerAdapter將照顧其餘。

0

查看您的getCount()方法返回viewPager中項目的確切數目。是的,FragmentStatePagerAdapter也會計數。

0

我已經結束了與混合基於遇到以下知識的解決方案:

  • 您可以在尾部增加一個新的Fragment沒有問題。
  • 您無法讀取以前刪除的Fragment,因爲它有時會導致java.lang.IllegalStateException: Can't change tag of fragment,所以您必須克隆它。
  • 要刪除Fragment,您必須在方法getItemPosition(Object object)中返回PagerAdapter.POSITION_NONE,並從FragmentManager中刪除Fragment
  • 如果要在與尾部不同的其他位置添加/刪除/替換,必須從您正在更改的位置移除所有內容,直到結束,執行所有操作,然後讀取您刪除的(克隆的)Fragment

這是一個完整的FragmentActivity代碼與FragmentPagerAdapter有添加,刪除和替換選項卡3種方法:

public class TabTestActivity extends FragmentActivity implements 
     ActionBar.TabListener { 
    private SectionsPagerAdapter mSectionsPagerAdapter; 
    private ViewPager mViewPager; 
    private static int tabCount = 0; 
    private static String labelString = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     labelString = getString(R.string.title_section); 
     setContentView(R.layout.activity_tab_test); 
     final ActionBar actionBar = getActionBar(); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     mSectionsPagerAdapter = new SectionsPagerAdapter(
       getSupportFragmentManager()); 
     mViewPager = (ViewPager) findViewById(R.id.pager); 
     mViewPager.setAdapter(mSectionsPagerAdapter); 
     mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 
        @Override 
        public void onPageSelected(final int position) { 
         (new Handler()).postDelayed(new Runnable() { 

          @Override 
          public void run() { 
           actionBar.setSelectedNavigationItem(position); 
          } 

         }, 1); 
        } 
       }); 

     for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) { 
      actionBar.addTab(actionBar.newTab() 
        .setText(mSectionsPagerAdapter.getPageTitle(i)) 
        .setTabListener(this)); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.tab_test, menu); 
     return true; 
    } 

    public void addNewTab() { 
     int position = (mSectionsPagerAdapter.getCount() > 0 ? mViewPager.getCurrentItem() : 0); 
     mSectionsPagerAdapter.insertFragment(position); 
     mViewPager.setCurrentItem(position, true); 
    } 

    public void removeTab() { 
     if (mSectionsPagerAdapter.getCount() > 0) { 
      int position = mViewPager.getCurrentItem(); 
      mSectionsPagerAdapter.removeFragment(position); 
     } 
    } 

    public void replaceTab() { 
     if (mSectionsPagerAdapter.getCount() > 0) { 
      int position = mViewPager.getCurrentItem(); 
      mSectionsPagerAdapter.replaceFragment(position);    
      mViewPager.setCurrentItem(position, false); 
     } 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case R.id.action_add_tab: 
      addNewTab(); 
      return true; 
     case R.id.action_remove_tab: 
      removeTab(); 
      return true; 
     case R.id.action_replace_tab: 
      replaceTab(); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onTabSelected(ActionBar.Tab tab, 
      FragmentTransaction fragmentTransaction) { 
     mViewPager.setCurrentItem(tab.getPosition()); 
    } 

    @Override 
    public void onTabUnselected(ActionBar.Tab tab, 
      FragmentTransaction fragmentTransaction) { 
    } 

    @Override 
    public void onTabReselected(ActionBar.Tab tab, 
      FragmentTransaction fragmentTransaction) { 
    } 

    public class SectionsPagerAdapter extends FragmentPagerAdapter { 

     private List<Fragment> currentFragments; 
     private FragmentManager fragmentManager; 

     public SectionsPagerAdapter(FragmentManager fm) { 
      super(fm); 
      fragmentManager = fm; 
      currentFragments = new ArrayList<Fragment>(); 
     } 

     public void insertFragment(int position) { 
      // Remove fragments from position 
      List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size())); 
      int i = currentFragments.size() - 1; 
      int j = -1; 
      int k = i; 
      while (i >= position) { 
       currentFragments.remove(i); 
       i--; 
       j++; 
      } 
      notifyDataSetChanged(); 
      final ActionBar actionBar = getActionBar(); 
      while (k >= position) { 
       actionBar.removeTabAt(k); 
       k--; 
      } 
      android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction(); 
      while (j >= 0) { 
       Fragment fragmentToRemove = fragmentsToRemove.get(j); 
       transaction.detach(fragmentToRemove); 
       transaction.remove(fragmentToRemove); 
       j--; 
      } 
      transaction.commit(); 
      fragmentManager.executePendingTransactions(); 
      notifyDataSetChanged(); 
      // Add new fragment 
      Fragment fragment = new DummySectionFragment(); 
      currentFragments.add(position, fragment); 
      notifyDataSetChanged(); 
      actionBar.addTab(actionBar.newTab() 
        .setText(mSectionsPagerAdapter.getPageTitle(position)) 
        .setTabListener(TabTestActivity.this), position); 
      // Readd fragments 
      if (fragmentsToRemove.size() > 0) { 
       i = 1; 
       for (Fragment fragmentToRemove : fragmentsToRemove) { 
        currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragmentToRemove)); 
        notifyDataSetChanged(); 
        actionBar.addTab(actionBar.newTab() 
          .setText(mSectionsPagerAdapter.getPageTitle(position + i)) 
          .setTabListener(TabTestActivity.this), position + i); 
        i++; 
       } 
      } 
     } 

     public void removeFragment(int position) { 
      // Remove fragments from position 
      List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size())); 
      int i = currentFragments.size() - 1; 
      int j = -1; 
      int k = i; 
      while (i >= position) { 
       currentFragments.remove(i); 
       i--; 
       j++; 
      } 
      notifyDataSetChanged(); 
      final ActionBar actionBar = getActionBar(); 
      while (k >= position) { 
       actionBar.removeTabAt(k); 
       k--; 
      } 
      android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction(); 
      while (j >= 0) { 
       Fragment fragmentToRemove = fragmentsToRemove.get(j); 
       transaction.detach(fragmentToRemove); 
       transaction.remove(fragmentToRemove); 
       j--; 
      } 
      transaction.commitAllowingStateLoss(); 
      fragmentManager.executePendingTransactions(); 
      notifyDataSetChanged(); 
      // Readd fragments (except one) 
      if (fragmentsToRemove.size() > 1) { 
       i = 0; 
       for (Fragment fragment : fragmentsToRemove.subList(1, fragmentsToRemove.size())) { 
        currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragment)); 
        notifyDataSetChanged(); 
        actionBar.addTab(actionBar.newTab() 
          .setText(mSectionsPagerAdapter.getPageTitle(position + i)) 
          .setTabListener(TabTestActivity.this), position + i); 
        i++; 
       } 
      } 
     } 

     public void replaceFragment(int position) { 
      // Remove fragments from position 
      List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size())); 
      int i = currentFragments.size() - 1; 
      int j = -1; 
      int k = i; 
      while (i >= position) { 
       currentFragments.remove(i); 
       i--; 
       j++; 
      } 
      notifyDataSetChanged(); 
      final ActionBar actionBar = getActionBar(); 
      while (k >= position) { 
       actionBar.removeTabAt(k); 
       k--; 
      } 
      android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction(); 
      while (j >= 0) { 
       Fragment fragmentToRemove = fragmentsToRemove.get(j); 
       transaction.detach(fragmentToRemove); 
       transaction.remove(fragmentToRemove); 
       j--; 
      } 
      transaction.commit(); 
      fragmentManager.executePendingTransactions(); 
      notifyDataSetChanged(); 
      // Add new fragment 
      Fragment fragment = new DummySectionFragment(); 
      currentFragments.add(position, fragment); 
      notifyDataSetChanged(); 
      actionBar.addTab(actionBar.newTab() 
        .setText(mSectionsPagerAdapter.getPageTitle(position)) 
        .setTabListener(TabTestActivity.this), position); 
      // Readd fragments (except one) 
      if (fragmentsToRemove.size() > 0) { 
       i = 1; 
       for (Fragment fragmentToRemove : fragmentsToRemove.subList(1, fragmentsToRemove.size())) { 
        currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragmentToRemove)); 
        notifyDataSetChanged(); 
        actionBar.addTab(actionBar.newTab() 
          .setText(mSectionsPagerAdapter.getPageTitle(position + i)) 
          .setTabListener(TabTestActivity.this), position + i); 
        i++; 
       } 
      } 
     } 

     @Override 
     public Fragment getItem(int position) { 
      if (currentFragments == null) { 
       currentFragments = new ArrayList<Fragment>(); 
      } 
      while (currentFragments.size() <= position) { 
       currentFragments.add(null); 
      } 
      if (currentFragments.get(position) != null) { 
       return currentFragments.get(position); 
      } 
      Fragment fragment = new DummySectionFragment(); 
      currentFragments.set(position, fragment); 
      return fragment; 
     } 

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

     @Override 
     public int getItemPosition(Object object) { 
      int position = currentFragments.indexOf(object); 
      if (position == -1) { 
       return PagerAdapter.POSITION_NONE; 
      } 
      return position; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      return ((DummySectionFragment)getItem(position)).getTitle(); 
     } 
    } 

    public static class DummySectionFragment extends Fragment { 
     private int sectionNumber; 

     public DummySectionFragment() { 
      super(); 
      sectionNumber = ++tabCount; 
     } 

     public static DummySectionFragment cloneExistingFragment(DummySectionFragment fragment) { 
      DummySectionFragment cloned = new DummySectionFragment(); 
      // Hack for avoiding autoincrement 
      --tabCount; 
      cloned.sectionNumber = fragment.getSectionNumber(); 
      return cloned; 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
       Bundle savedInstanceState) { 
      View rootView = inflater.inflate(R.layout.fragment_tab_test_dummy, 
        container, false); 
      TextView dummyTextView = (TextView) rootView 
        .findViewById(R.id.section_label); 
      dummyTextView.setText(String.format(labelString, sectionNumber)); 
      return rootView; 
     } 

     public int getSectionNumber() { 
      return sectionNumber; 
     } 

     public String getTitle() { 
      return String.format(labelString, sectionNumber); 
     } 
    } 

} 
相關問題