您的位置:首页 > 移动开发 > Android开发

Android开发笔记 ViewPager 嵌套 RecyclerView instantiateItem数据初始化错位问题

2017-08-19 19:08 956 查看
       在应用开发过程中,使用ViewPager嵌套RecyclerView实现整屏的横滑是很常见的需求。在为ViewPager设置adapter的时候,需要重写初始化方法,
   public Object instantiateItem(ViewGroup container, int position) {}来告诉ViewPager对应每个position展示什么View,在这个方法中将

position对应的view  add进container,返回该view即可。
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.detail, null);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);

ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null) {
parent.removeView(view);
}
container.addView(view);

if (mPresenter == null) {
initPresenter();
}
mPresenter.updateRecyclerView(pagerDataList.get(position), recyclerView);
return view;
}
在MVP模式的项目中,告诉Presenter该position页需要请求的数据,将数据放入recyclerView即可。但是,在ViewPager初始化的时候,
instantiateItem()方法会连续执行position = 0 和 position = 1 两次,当presenter需要去网络请求position = 0数据完成后,presenter持有的
recyclerView引用已经指向了position = 1的view内的recyclerView对象,数据也会被贴到position = 1的页面里。在viewPager的滑动过程中,每次滑动
预加载下一页时instantiateItem只会执行一次,网络正常的情况下,不会出现错乱问题。
解决办法:维护一个任务队列,在每次presenter请求数据时,将数据的标记(id)与recyclerView存入对列,数据请求回来后,判断是否有等待的任务,有等待的
任务,则任务出队,请求数据,给recyclerView贴数据。
public static class Task {
private int id;
private RecyclerView recyclerView;

public int getId() {
return id;
}

public RecyclerView getRecyclerView() {
return recyclerView;
}

public Task (int id, RecyclerView recyclerView) {
this.id = id;
this.recyclerView = recyclerView;
}
}

presenter中定义一个队列变量,
private Queue<Task> caCheTaskQueue = new LinkedList<Task>();
每次需要请求一个也页面的数据的时候,判断队列里有没有缓存任务,并将本次任务入队
if (caCheTaskStack.isEmpty()) {
initRecyclerView();//请求数据并交给recyclerView初始化
}
caCheTaskStack.offer(new Task(currentPageId, recyclerView));//入队
在initRecyclerView()网络请求回调里,任务出队,再判断是否有任务等待。
caCheTaskStack.poll();//本次任务出队
if (!caCheTaskStack.isEmpty()) {
Task task = caCheTaskStack.peek();//缓存任务读取
currentPageId = task.getId();
recyclerView = task.getRecyclerView();
initRecyclerView();//请求数据并交给recyclerView初始化
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐