2012-09-25 85 views
92

我無法在FragmentPagerAdapter中重複使用片段。使用destroyItem()方法,它正在刪除片段,但仍然沒有再次調用getItem()..只有2-3圖像,所以我現在用FragmentPagerAdapter相反FragmentStatePagerAdapter的..FragmentPagerAdapter getItem不叫

public class ExamplePagerAdapter extends FragmentPagerAdapter { 

    ArrayList <String> urls; 
    int size = 0; 
    public ExamplePagerAdapter(FragmentManager fm, ArrayList <String> res) { 
     super(fm); 
     urls = res; 
     size = urls.size(); 
    } 

    @Override 
    public int getCount() { 
     if (urls == null) { 
      return 0; 
     } else { 
      return size; 
     } 

    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     FragmentManager manager = ((Fragment) object).getFragmentManager(); 
     FragmentTransaction trans = manager.beginTransaction(); 
     trans.remove((Fragment) object); 
     trans.commit(); 
    } 

    @Override 
    public Fragment getItem(int position) { 

     Fragment fragment = new FloorPlanFragment(); 
     Bundle b = new Bundle(); 
     b.putInt("p", position); 
     b.putString("image", urls.get(position)); 
     Log.i("image", "" + urls.get(position)); 
     fragment.setArguments(b); 
     return fragment; 
    } 
} 

並在FragmentActivity,

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 
+2

是否有一個特殊的原因,你覆蓋'destroyItem()'?這沒有必要。 – CommonsWare

+0

重新初始化使用FragmentStatePagerAdapter 也可以調用,當你覆蓋它 super.destroyItem(容器,位置,對象); – faiziii

回答

249

KISS答:

簡單使用FragmentStatePagerAdapter inste廣告FragmentPagerAdapter

我得到了答案。首先我想刪除這個問題,因爲我正在做一個非常愚蠢的錯誤,但這個答案將有助於面臨同樣問題的人,而不是FragmentPagerAdapter,使用FragmentStatePagerAdapter

由於@BlackHatSamurai在評論中提到:

這部作品的原因是因爲FragmentStatePagerAdapter破壞 爲未使用的片段。 FragmentPagerAdapter沒有。

+6

謝謝,你救了我。 –

+1

謝謝。真的幫我出去了 –

+0

我想知道爲什麼呢? –

2

有兩種不同的情況:1。 )您有相同的佈局,每尋呼機: 在這種情況下,它會更好,如果你通過PagerAdapter擴展您的自定義適配器 並返回一個佈局。

2)你必須爲每一個尋呼機不同的佈局: 在這種情況下,它會更好,如果你通過FragmentStatePagerAdapter擴展您的自定義適配器 併爲每尋呼機返回不同fragmets。

116

使用FragmentStatePagerAdapter沒有完全解決我的問題,這是一個類似的問題,其中onCreateView未被視圖尋呼機中的子片段調用。我實際上是將我的FragmentPagerAdapter嵌套在另一個Fragment之內,因此FragmentManager在所有這些中共享,因此保留了舊片段的實例。解決的辦法是將getChildFragmentManager的一個實例提供給我的主機片段中的FragmentPagerAdapter的構造函數。喜歡的東西...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager()); 

getChildFragmentManager()方法是通過片段訪問,這個工作對我來說,因爲它返回一個私人FragmentManager該片斷專門爲這是需要嵌套的片段的情況。我希望這可以幫助那些可能遇到同樣問題的人!

  • 但是請記住使用getChildFragmentManager()您的最低API版本至少要包含17 (4.2),所以這可能會在你扔的齒輪扳手。當然,如果你使用支持庫v4的片段,你應該沒問題。
+18

這是正確的答案。問題在於嵌套在其他片段中的片段應該使用getChildrenFragmentManager()而不是getFragmentManager()。 – shihpeng

+0

非常感謝,我永遠花了我的時間找到這個答案! – Shpongoloid

+0

我同意@shihpeng。這應該是正確的答案。 –

0

我發現,設置在標籤佈局的監聽器停止這個被稱爲,可能是因爲他們只有空間,一個監聽器tabLayout.setOnTabSelectedListener,而不是偵聽器的數組。

2

我做了@kanika和@ Jraco11發佈的內容,但我仍然遇到了問題。

所以,很多的變化後,我發現一個很適合我,並加入到我的FragmentPagerAdapter下一個代碼:

@Override 
    public int getItemPosition(Object object) { 
     return POSITION_NONE; 
    } 

根據我讀,getItemPosition用來通知ViewPager是否刷新一個項目,並避免更新如果可見位置上的項目沒有改變。

0

覆蓋long getItemId (int position)

FragmentPagerAdapter緩存它創建使用getItem片段。我正面臨同樣的問題 - 即使撥打電話notifyDataSetChanged()getItem未被調用。

這實際上是一個功能,而不是一個錯誤。您需要覆蓋getItemId,以便您可以正確重複使用您的片段。由於您正在移除碎片,因此您的位置正在改變。如在該文檔中提到:

long getItemId (int position)

返回在給定位置處的項目的唯一標識符。

默認實現返回給定位置。 如果項目的位置可以更改,子類應該重寫此方法。

只要爲每個片段提供一個唯一的ID,就完成了。

使用FragementStatePagerAdapter或返回POSITION_NONEint getItemPosition (Object object)是錯誤的。你不會得到任何緩存。

相關問題