我有一个ViewPager,它从服务器传下来的数据绘制其页面 (视图)。偶尔,服务器会发送新数据,这将重新排序视图(有时还会添加新视图),我需要在 Android 设备上实现无缝切换,而用户正在查看特定片段。
当从服务器下载新数据时,我已经设置它调用 notifyDataSetChanged() 方法,但似乎它仍将当前查看的幻灯片左右两侧的缓存版本保留下来,而这些版本可能会随着重新排序而更改。我已经查看了这个问题:ViewPager PagerAdapter not updating the View 并实施了第一个解决方案,除了重新加载当前正在查看的幻灯片外,其他都很好用,这对我的目的不起作用。我浅显地研究了在同一页的第二个答案中提出的 setTag() 方法的实现方式,这可以用于更新幻灯片中的信息,但不能帮助我重新排序它们。
有没有一种方法可以在幕后重新排列所有幻灯片而不会引起当前查看的幻灯片中断?
TIA
编辑:添加代码并要求进一步澄清
这是我的 Adapter 类。
当从服务器下载新数据时,我已经设置它调用 notifyDataSetChanged() 方法,但似乎它仍将当前查看的幻灯片左右两侧的缓存版本保留下来,而这些版本可能会随着重新排序而更改。我已经查看了这个问题:ViewPager PagerAdapter not updating the View 并实施了第一个解决方案,除了重新加载当前正在查看的幻灯片外,其他都很好用,这对我的目的不起作用。我浅显地研究了在同一页的第二个答案中提出的 setTag() 方法的实现方式,这可以用于更新幻灯片中的信息,但不能帮助我重新排序它们。
有没有一种方法可以在幕后重新排列所有幻灯片而不会引起当前查看的幻灯片中断?
TIA
编辑:添加代码并要求进一步澄清
这是我的 Adapter 类。
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {
ContestEntriesModel entries;
public ScreenSlidePagerAdapter(FragmentManager fm, ContestEntriesModel Entries) {
super(fm);
this.entries = Entries;
}
@Override
public long getItemId(int position) {
return entries.entries[position].ContestEntryId;
}
@Override
public int getItemPosition(Object object) {
android.support.v4.app.Fragment f = (android.support.v4.app.Fragment)object;
for(int i = 0; i < getCount(); i++){
android.support.v4.app.Fragment fragment = getItem(i);
if(f.equals(fragment)){
return i;
}
}
return POSITION_NONE;
}
@Override
public android.support.v4.app.Fragment getItem(int position) {
long entryId = getItemId(position);
//Log.d("EntryIds",Integer.toString(entryId));
if(mItems.get(entryId) != null) {
return mItems.get(entryId);
}
Fragment f = ScreenSlidePageFragment.create(position);
mItems.put(entryId, f);
return f;
}
@Override
public int getCount() {
return NUM_PAGES;
}
}
当新的有效负载从服务器传来时,我使用以下内容:
@Override
protected void onPostExecute(ContestEntriesModel entries) {
Fragment currentFragment = ContestEntries.mItems.get(ContestEntries.CurrentEntryId);
Log.d("fromUpdate",Long.toString(ContestEntries.CurrentEntryId));
ContestEntries.Entries = entries;
ContestEntries.NUM_PAGES = ContestEntries.Entries.entries.length;
ContestEntries.mPagerAdapter.notifyDataSetChanged();
ContestEntries.mPager.setCurrentItem(ContestEntries.mPagerAdapter.getItemPosition(currentFragment));
}
getItem(int)
会每次创建一个新的 Fragment,因为你没有实现某种形式的缓存。由于你每次都创建一个新的 Fragment,getItemPosition(Object)
将始终返回POSITION_NONE
,这就是为什么它会重新加载当前的幻灯片。 - ReiniergetItem(int)
的返回值,因为对象引用不同。虽然您可以通过在Fragment中实现一个“equals()”方法来克服这个问题,但这仍意味着每次调用getItem(int)
都会创建一个新的Fragment - 这是对资源的无用浪费。 - Reinier