0

我的MainActivity包含一個viewPager。替換Viewpager中的一個片段(notifyDataSetChanged不起作用)

在MainActivity.java中,我爲viewpager設置了適配器。該適配器擴展了FragmentStatePagerAdapter。我想要替換的片段是一個 cameraFragment。因此,當用戶點擊切換照相機按鈕時,我想現在顯示照相機片段,這次打開前置攝像頭。

在點擊開關Camera按鈕時,我從傳遞給自定義適配器的片段的數組列表中刪除片段。我添加新的片段並調用notifydatasetchanged。但是,這不會導致添加新片段。我如何實現在支持我自定義片段狀態尋呼機適配器的viewpager中動態替換片段? 代碼:

mainPageFragments = new ArrayList<>(); 
mainPageFragments.add(new ResultsFragment_()); 
mainPageFragments.add(DemoCameraFragment_.newInstance(false)); 
pagerAdapter = new MainViewPagerAdapter(getSupportFragmentManager(),mainPageFragments); 

要更換片段:在收到相關的事件怎麼辦,

mainPageFragments.remove(1); 
    if (event.getCameraState().equals(CameraSwitchButton.CameraTypeEnum.BACK)) { 
     mainPageFragments.add(DemoCameraFragment.newInstance(false)); 
    } else { 
     mainPageFragments.add(DemoCameraFragment.newInstance(true)); 

    } 
    // Not Working... 
    pagerAdapter.notifyDataSetChanged(); 

適配器代碼:

public class MainViewPagerAdapter extends FragmentStatePagerAdapter { 

ArrayList<Fragment> fragmentsArray; 

public MainViewPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragmentsArray) { 
    super(fm); 
    this.fragmentsArray = fragmentsArray; 
} 

@Override 
public Fragment getItem(int position) { 
    return fragmentsArray.get(position); 
} 

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

@Override 
public int getItemPosition(Object object) { 
    return super.getItemPosition(object); 
} 
} 
+0

發佈一些代碼你已經完成了 – Mano

+0

@Mano。有關如何更新/替換片段的任何想法?顯然我錯過了一些東西。我不想重置適配器。它看起來像一個昂貴的操作(如果頁數/片段數量增加了,而且我只需要替換一個片段,所以重新實例化每個其他片段就沒有任何意義了) – Rohan

+0

請發佈代碼MainViewPagerAdapter。 – Okas

回答

2

你MainViewPagerAdapter.getItemPosition是你的問題的原因。

默認實現總是返回POSITION_UNCHANGED。對於尋呼機刪除你的片段,你必須返回PagerAdapter.POSITION_NONE去除被刪除的片段。

此外,您目前的設計與FragmentStatePagerAdapter的想法相矛盾。來自FragmentStatePagerAdapter documentation:「當有大量頁面時,這個版本的頁面更有用,工作更像列表視圖,當用戶看不到頁面時,它們的整個片段可能被破壞,只保留已保存的這使得分頁器能夠保持與每個訪問頁面相關的內存少得多,而不是以FragmentPagerAdapter爲代價,但代價是在頁面之間切換時可能會產生更多開銷。「

您當前的實現將所有片段保存在一個數組中,因此失敗了此機制。正確的實現是在MainViewPagerAdapter.getItem方法中創建片段,並讓適配器根據需要處理片段生命週期。

+0

即使我用這種方式來實現適配器,我該如何替換這個片段?我已經閱讀了getItemPosition的默認實現,我使用FragmentStatePageAdapter的原因是有一個很好的機會viewpager中的頁面數量會增加,我仍然無法弄清楚getItemPosition方法應該做些什麼來解決我的問題,謝謝。 – Rohan

+1

你必須分別跟蹤你想要保留的碎片和要刪除的碎片。然後,當發生變化時,你必須調用notifyDataSetChanged()。傳呼機然後將調用您的適配器getItemPosition方法。您必須將POSITION_NONE返回給您想要刪除的人,然後傳呼機將爲您刪除這些人。 – Okas

+0

謝謝@Okas。我根據您的帖子進行了更改,並在下面發佈了答案。 – Rohan

0

感謝@Okas。我對FragmentStatePagerAdapter子類中的getItemPosition進行了以下更改。

@Override 
public int getItemPosition(Object object) { 
    if (object instanceof DemoCameraFragment_) 
     return POSITION_NONE; 
    return super.getItemPosition(object); 
} 

我將日誌添加到兩個碎片的OnCreate以確認它們是否得到重新創建。根據我的要求,只有第二個片段被重新創建。

相關問題