我尝试使用扩展的 FragmentStatePagerAdapter 和扩展的 FragmentPagerAdapter 来实现我正在尝试的东西,但似乎都不起作用。我正在从我的服务器发送一个 JSON 对象以填充 android 客户端上的对象模型。在第一次加载时,一切正常,我可以从头到尾很好地浏览页面。这是我的对象模型:
ContestEntriesModel.java
public class ContestEntriesModel {
public int ContestId;
public String ContestName;
public ContestEntryModel[] entries;
}
如您所见,有一个 ContestEntryModel 数组。这些模型中的每一个都如下所示:
ContestEntryModel.java
public class ContestEntryModel {
public long ContestEntryId;
public int UserId;
public String FullName;
public int Comments;
public string ImageUrl;
}
如上所述,当第一个数据有效负载从服务器下来时,我在 ContestEntryModel[] 数组中的每个项目中填充一个片段,其中包含来自该模型的数据(包括来自互联网资源 (ImageUrl) 的图像),并且效果很好. 我可以滑动直到我的手指流血,世界上一切都很好。
我现在正尝试从服务器向下发送另一个有效负载,其中数组中的项目以不同的顺序(我最终也会添加新项目,但一次一步)。我在 StackOverflow 上搜索了一个解决方案,昨天发布了一个问题,让我接近了我需要的地方(感谢 Reinier),但我仍然在努力让我的所有片段重新排序并拥有适配器完全刷新新订单。适配器似乎缓存了一些幻灯片(与我当前正在查看的幻灯片相邻的那些)并且它们不会“刷新”,直到我将一些图像滑过它们然后返回。昨天的麻烦是当新数据从我正在工作的服务器上下来时,当前查看的幻灯片无法“刷新”......有点。让' s 说我的数组中有 7 个项目,我在第一次加载时滑动到幻灯片 #3(索引 2)。然后我从服务器推送新数据,该服务器只是对数组进行反向排序。当前查看的幻灯片(幻灯片#3)然后应该移动到索引位置 4,我应该只能向右滑动 2 次(索引位置 5 和 6)。相反,它正在记住该幻灯片的当前索引位置(索引 2)并将其保留在那里。正如我上面所说,幻灯片 #2(索引 1)和幻灯片 #4(索引 3)也正在维护中。我的预期行为是这些幻灯片应该围绕幻灯片#3(索引 2)反转位置。当前查看的幻灯片(幻灯片#3)然后应该移动到索引位置 4,我应该只能向右滑动 2 次(索引位置 5 和 6)。相反,它正在记住该幻灯片的当前索引位置(索引 2)并将其保留在那里。正如我上面所说,幻灯片 #2(索引 1)和幻灯片 #4(索引 3)也正在维护中。我的预期行为是这些幻灯片应该围绕幻灯片#3(索引 2)反转位置。当前查看的幻灯片(幻灯片#3)然后应该移动到索引位置 4,我应该只能向右滑动 2 次(索引位置 5 和 6)。相反,它正在记住该幻灯片的当前索引位置(索引 2)并将其保留在那里。正如我上面所说,幻灯片 #2(索引 1)和幻灯片 #4(索引 3)也正在维护中。我的预期行为是这些幻灯片应该围绕幻灯片#3(索引 2)反转位置。
这是我的 PagerAdapter 的实现(这是 FragmentStatePagerAdapter 而不是 FragmentPagerAdapter 的版本:
ScreenSlidePagerAdapter:
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ContestEntriesModel entries;
public ScreenSlidePagerAdapter(FragmentManager fm, ContestEntriesModel Entries) {
super(fm);
this.entries = Entries;
}
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)){
//Log.d("currentPosition",Integer.toString(i));
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;
}
}
目前我正在为适配器的活动设置一个静态属性(我在其他一些“外部”类中使用它),如下所示:
主要活动:
public class MainActivity extends FragmentActivity {
public static int NUM_PAGES = 0;
public static ViewPager mPager;
public static PagerAdapter mPagerAdapter;
public static ContestEntriesModel Entries;
public static HashMap<Long, android.support.v4.app.Fragment> mItems = new HashMap<Long, android.support.v4.app.Fragment>();
public static Long CurrentEntryId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.entries_layout);
GetEntriesTask task = new GetEntriesTask(43);
task.execute();
}
public void LoadEntries()
{
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), Entries);
mPager.setAdapter(mPagerAdapter);
mPager.setPageTransformer(true, new MyPageTransformer());
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
ContestEntries.CurrentEntryId = ContestEntries.Entries.entries[position].ContestEntryId;
Log.d("currentEntry",Long.toString(ContestEntries.CurrentEntryId));
invalidateOptionsMenu();
}
});
}
//the rest is omitted as it's not pertinent to my issue.
当一个新的数据加载从服务器上下来时,我只是将我的静态属性(条目)设置为新版本。我还尝试访问 PagerAdapter (条目)中的公共属性以直接修改它,但由于某种原因无法访问(即使类和属性都具有公共访问器)。我认为这就是问题所在,因为这是我需要修改的那个实例,但老实说,我的大脑在这一点上被炒了,我只是不确定。这是我用于更新的代码:
更新代码:
@Override
protected void onPostExecute(ContestEntriesModel entries) {
Fragment currentFragment = MainActivity.mItems.get(MainActivity.CurrentEntryId);
Log.d("fromUpdate",Long.toString(MainActivity.CurrentEntryId));
MainActivity.Entries = entries;
MainActivity.NUM_PAGES = MainActivity.Entries.entries.length;
//MainActivity.mItems.clear();
MainActivity.mPagerAdapter.notifyDataSetChanged();
MainActivity.mPager.setCurrentItem(MainActivity.mPagerAdapter.getItemPosition(currentFragment));
}
因此,使用它,它确实让我保持在当前幻灯片上(这是我需要的),但该幻灯片没有如上所述正确重新定位,其他相邻幻灯片也没有“刷新”。同样,假设我在幻灯片 #3 上,如果我在旧幻灯片 #2 仍然存在时向左滑动。如果我向左滑动两次,幻灯片 #1 会更新为“新”幻灯片(第一次加载的幻灯片 #7)。如果我再向右滑动一次,幻灯片#2 仍然存在(应该是幻灯片#6)。如果我然后再次向右滑动,我需要维护的“原始”幻灯片现在被替换为幻灯片 #5(同样,该数字来自原始负载)。如果我一直向右滑动到“新”幻灯片#5,我会再次看到原始幻灯片。那是它需要在新数据加载的位置,在那个位置。
我真诚地为这堵文字墙道歉,但我想如果我能提供尽可能多的代码,这会更有意义。我已经阅读了几种不同的方法来解决这个问题,但我无法解决任何特别适合我需求的方法。
任何建议/代码帮助将不胜感激。