2012-06-22 63 views
2

我想在ViewPager的首頁添加一個新的視圖。 我的適配器是這樣的:Android ViewPager預先安裝新視圖

public class PagerAdapter extends FragmentPagerAdapter { 

    private final List<Fragment> fragments; 

    public PagerAdapter(FragmentManager fm, List<Fragment> fragments) { 
     super(fm); 
     this.fragments = fragments; 
    } 

    @Override 
    public Fragment getItem(int index) { 
     return fragments.get(index); 
    } 

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

    public void add(int i, ImageFileObject imageFile) { 
     ImageViewFragment f = new ImageViewFragment(); 
     f.setImage(imageFile); 
     fragments.add(0, f); 
     notifyDataSetChanged(); 
    } 

    public void add(ImageFileObject imageFile) { 
     ImageViewFragment f = new ImageViewFragment(); 
     f.setImage(imageFile); 
     fragments.add(f); 
     notifyDataSetChanged(); 
    } 

} 

但調用時添加(0,aImageFile)該項目不前加到片列表。 (它甚至沒有附加)。

任何想法?

+0

嘗試閱讀這裏:http://stackoverflow.com/questions/10849552/android-viewpager-cant-update-dynamically –

回答

0

問題實際上是通過notifyDataSetChanged。只需添加到您的適配器:

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

不過,我想你會得到其他問題時,適配器實際上是嘗試再次調用getItem。這些問題將符合「已添加片段」的要求。

2

更新:你在評論中描述的問題是真實的,我在第一次測試中錯過了它。在分析了FragmentPagerAdapter的源代碼之後,我意識到我們所需要做的就是以不會爲不同的片段項目返回相同ID的方式覆蓋getItemId()。例如。當前默認的實現將只返回位置作爲片段的id,這將不會對這種情況下的工作:

public long getItemId(int position) { 
    return position; 
} 

我更新這個答案,請看看。像以前一樣,我已經測試了這段代碼,並且你所描述的問題現在還沒有發生。


你唯一需要的就是通過自己List保持片段的引用,這是由FragmentPagerAdapter爲你做。就我所知,它也不是一個好的做法。而且,即使你從getItemPosition()返回POSITION_NONE其他答案(S)的建議,你將結束與異常

產生的原因:java.lang.IllegalStateException:無法更改片段的標籤。

這是因爲你正試圖通過在第0指數(這會導致其他片段重新定位)和ViewPager基於位置分配標籤添加片段在你的List重新定位活着Fragment秒。

保持這一切在心中,這裏是一個測試,工作修改適配器:

public class PagerAdapter extends FragmentPagerAdapter { 
public static class FragmentInfo { 
    public String classz; 
    public ImageFileObject imageFile; 


    public static long IDS; 
    public long id; 

    public FragmentInfo(){ 
     id = IDS++; 
    } 
} 



private final List<FragmentInfo> fragments; 
private Context context; 

public PagerAdapter(FragmentManager fm, List<FragmentInfo> fragments, 
     Context context) { 
    super(fm); 
    this.fragments = fragments; 
    this.context = context; 
} 

@Override 
public Fragment getItem(int index) { 
    FragmentInfo info = fragments.get(index); 
    ImageViewFragment frag = (ImageViewFragment) Fragment.instantiate(
      context, info.classz, /* null arguments*/ null); 
    frag.setImage(info.imageFile); 
    return frag; 
} 

@Override 
public long getItemId(int position) { 
    return fragments.get(position).id; 
} 

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

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

public void add() { 
    FragmentInfo f = new FragmentInfo(); 
    f.classz = ImageViewFragment.class.getName(); 
    fragments.add(0, f); 
    notifyDataSetChanged(); 
} 
} 

請相應地改變你的代碼。

+0

雖然使用你的代碼不會在添加到開始時拋出任何錯誤,但它仍然沒有工作。添加前可見的頁面保留相同的索引,只有先前未加載的頁面纔會獲取更新的索引。例如,如果我在頁面0上並且「預先加載」一個頁面,則無法滾動到左側,因爲當前索引爲0,而滾動到右側給出頁面0的副本,因爲創建了新實例第1頁,現在是前一頁0 ... – Ratzor

+0

我不明白你在說什麼。你是說使用這種技術只是保持複製頁面0?你確定嗎?你如何檢測滾動到右側給出頁面0的副本? –

+0

問題是,該方法不會更新已經顯示的頁面。 所以,舉例來說如果我是第10頁上,在前面加上一個頁面,並移動到第11頁,這還沒有實例化,它會顯示10頁(這是正確的,因爲我請求頁面索引11 ,由於預先決定頁面現在是第10頁),問題在於索引10上的頁面保持爲第10頁,因爲它不會重新實例化。 – Ratzor

相關問題