ViewPager切换Fragment时ListView数据不更新

来源:互联网 发布:程序员项目经验 编辑:程序博客网 时间:2024/05/18 13:09

问题描述:

开发中常会遇见这样的场景:用一个ViewPager嵌套多个Fragment来切换页面展示数据,但是如果Fragment展示的数据是用ListView、GridView、RecyclerView等滑动控件来展示的,那么这样的Fragment经常会出现白屏,即ListView等控件没有刷新数据,导致出现白屏。(这个问题很早就出现过,当时做了下笔记,今天无意之间又遇见了,随手把之前的笔记贴上)

问题分析:

出现这么的原因一般是我们通常都会对adapter做这样的判断:
if (adapter == null) {            adapter = new BusinessAdapter(R.layout.item_business, businessList);            mIView.initAdapter(adapter);        } else {            adapter.notifyDataSetChanged();        }

只有adapter不为null时,我们new一个adapter,同时会在构造方法中传递一个数据集合,这个数据集合会同adapter 进行数据的绑定,在加载更多数据的时候不在newadapter,而是notifyDataSetChanged,需要注意的时候,调用notifyDataSetChangednotifyDataSetChanged刷新数据,必须保证在newadapter时传入的集合是同一个集合,否则会出现adapter中的数据为空,导致白屏出现。

产生问题的具体代码:

看一下我产生这个问题的场景、代码以及对问题的再次分析:
ViewPager中有6个Fragment,其中两个是用RecyclerView来展示数据的,这两个Fragment我都是在onActivityCreate()方法中调用网络请求,获取完数据后对数据进行了整理,存放到了集合中,之后调用了initAdapter()方法,在这个方法中new 了adapter,然后让RecyclerView与adapter进行绑定:
@Override    public void onSucess(Object data, int page, String type) {        // 获取完数据后对数据进行整理        BusinessBean businessBean = (BusinessBean) data;        List<BusinessBean.BusinessDetails> businessInfo = businessBean.getSjinfo();        if (businessInfo.size() != 0) {            if (page == 1) businessList.clear();            businessList.addAll(businessInfo);        }        changeLayout(businessList.size());        initBusinessAdapter();//调用创建adapter的方法    }
initBusinessAdapter的方法如下:
private void initBusinessAdapter() {        if (adapter == null) {            adapter = new BusinessAdapter(R.layout.item_business, businessList);            mIView.initAdapter(adapter);//RecyclerView和adapter进行绑定        } else {            adapter.notifyDataSetChanged();        }    }
在第一次切换到这两个页面时数据显示是没有问题的,但是切换到其他页面再次切换回来时发现Fragment为白屏。
那就通过代码试一下问题的原因:
我们先把判断adapter是否为空的代码去掉,每次进入页面或者通过上下啦刷新更多数据都重新new adapter,测试一下发现,不管如何切换ViewPager的页面,fragment都不会再白屏了,但是问题是每次下拉刷新和上啦加载都要new一个新的adapter,太不合理了。而且在我们重新newadapter时就不会出现白屏,说明在之前的代码中重新切换到该Fragment时,执行的是adapter != null下面的notifyDataSetChanged方法,通过打印日志我们看一下是否是这样:
private void initBusinessAdapter() {        if (adapter == null) {            Logger.e("notifydata--busi1 =" + businessList.size());            adapter = new BusinessAdapter(R.layout.item_business, businessList);            mIView.initAdapter(adapter);        } else {notifyDataSetChanged            Logger.e("notifydata--busi2 = " + businessList.size());            adapter.notifyDataSetChanged();        }    }

发现确实是走了notify的方法,说明集合可能不一样,但是集合就是成员变量,没办法重新再new一个,那就有可能是ListView和adapter失去了关联导致的,网上有一种说法是ListView、RecyclerView销毁了,为null,但是通过实践打印发现并不为null,所以可能是两者失去了关联,如果是这个原因的话,那就每次进入时都关联一次,在onActivityCreated方法中再次进行关联:
if (adapter != null) {recyclerView.setAdapter(adapter);}
这样做之后,发现的确没有问题了。




阅读全文
0 0