adapter.notifyDataSetChanged()失效解决方案
来源:互联网 发布:js将字符串转换为json 编辑:程序博客网 时间:2024/05/22 07:53
谈起这个方法我相信基本每个接触一点Android开发的都用到过,但是好多时候并不是我们使用错了,而是无意之间的写法导致我们.notifyDataSetChanged()突然失去了效果,让我们摸不着头脑,下面根据自己的使用经验总结三种解决方法。
1.数据源没有更新,调用notifyDataSetChanged无效。
针对这个我们可以打断点看数据源发送变化没来解决。
2.adapter初始化时绑定的数据集合的地址所指向的数据没有发送改变。
这句话我们听着感觉蛮拗口的,下面我写一个例子分析分析:
//网络请求的数据 public List<String> mDatas== new ArrayList<>();; /*** 网络请求*/ @Overrideprotected void initViews(Bundle savedInstanceState) { MyAdapter mAdapter = new MyAdapter(); mListView.setAdapter(mAdapter); dogetData(); } private void dogetData() { //----网络请求代码注释---------- mDatas=response.getResult();//*表示网络请求成功写法一* for(int i=0;i<response.getResult().size();i++){ //*表示网络请求成功写法二* mDatas.add(response.getResult().get(i)); } //----------==== refreshUI(); } public void refreshUI(){ //刷新适配器 mAdapter.notifyDataSetChanged(); }/** 自定义的适配器 */ class MyAdapter extends BaseAdapter{ @Override public int getCount() { if(mDatas!=null){ return mDatas.size(); } return 0; } @Override public Object getItem(int position) { if(mDatas!=null){ return mDatas.get(position); } return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv = new TextView(getActivity()); tv.setText(mDatas.get(position)); return tv; } }
观察上面的网络请求部分的两种写法,首先我要说明的是写法一是错误的,写法二才是正确的。当我们无意之中写成写法一的这种形式就会造成adapter的适配器没有刷新,我们知道Java中基本类型和对象都是按值传递的,一个方法不能修改一个基本数据类型的参数,一个方法可以修改一个引用所指向的对象状态,但这仍然是按值调用而非引用调用,上面两种传递都进行了值拷贝的过程。
mDatas=response.getResult()
我们这个赋值是有问题的,这里我们新new了一个对象设置给了mDatas就是属于引用的值拷贝过程,这里属于浅拷贝Java拷贝概念,从堆内存中开辟一块空间给创造出来的对象,所以mDatas会重新指向这块新空间的地址而不指向原来初始化过程中指向的地址,所以
notifyDataSetChanged刷新的时候原地址上的数据源并没有发生任何变化,所以导致刷新失效,正确的写法应该是这样的:
for(int i=0;i<response.getResult().size();i++){ mDatas.add(response.getResult().get(i)); }
3.回调或者异步(线程调度)。
public List<NewsInfo > mDatas== new ArrayList<>(); Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//新的配置 .baseUrl(BASE_URL) .build(); MyService service = retrofit.create(MyService.class); service.news(userid, token,index) //获取Observable对象 .subscribeOn(Schedulers.newThread())//请求在新的线程中执行 .observeOn(Schedulers.io()) //请求完成后在io线程中执行 .doOnNext(new Action1<List<NewsInfo >>() { @Override public void call(List<NewsInfo > newsInfos) { saveInfo(newsInfos);//保存信息到本地// refreshUI(newsInfos); //位置一 } }) .observeOn(AndroidSchedulers.mainThread())//最后在主线程中执行 .subscribe(new Subscriber<List<NewsInfo >>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { //请求失败 } @Override public void onNext(List<NewsInfo >newsInfos) { //请求成功 refreshUI(newsInfos);//位置二 } }); public void refreshUI(List<NewsInfo >newsInfos){ //刷新适配器 for (NewsInfo news : newsInfos) { mDatas.add(news ); } mAdapter.notifyDataSetChanged(); }
这里我们使用一段RxJava来简单清晰展示网络异步请求的过程,当我们在位置一的时候更新刷新肯定是不行的因为我们在子线程进行操作ui,但我们在位置二进行更新是可以的,但我们千万别忘了加上切换到ui线程或者使用handler的时候注意发送至主线程。
- adapter.notifyDataSetChanged()失效解决方案
- adapter.notifyDataSetChanged()"失效"
- ViewPager调用Adapter.notifyDataSetChanged()失效
- 自定义adapter notifyDataSetChanged失效的解决
- Android adapter.notifyDataSetChanged失效的可能原因
- 关于ListView中adapter调用notifyDataSetChanged失效的原因总结
- 关于ListView中adapter调用notifyDataSetChanged失效的原因总结
- adapter.notifyDatasetChanged
- RecyclerView中Adapter调用notifyDataSetChanged无效时的解决方案
- 关于ListView中adapter调用notifyDataSetChanged失效的原因总结(转改)
- Adapter.notifyDataSetChanged()方法测试
- Android adapter.notifyDataSetChanged无效
- adapter.notifyDataSetChanged()无刷新
- Adapter——notifyDataSetChanged
- ListView adapter notifyDataSetChanged() track
- adapter.notifyDataSetChanged()不起作用
- RecyclerView.Adapter notifyDataSetChanged 不起作用
- adapter.notifyDataSetChanged()刷新不起作用
- Java类继承中的方法覆写overload
- 团体程序设计天梯赛-练习集 L2-016. 愿天下有情人都是失散多年的兄妹 解题报告
- 归并排序
- webuploader上传遇到的问题
- CCF2014-03-3命令行选项
- adapter.notifyDataSetChanged()失效解决方案
- 数据库查询时,in用exists代替例子
- ajax学习笔记
- 160. Intersection of Two Linked Lists
- python 迭代器与生成器 详解
- JAVA常用类库之String类
- Java HashMap的工作原理
- mysql优化
- 机器学习之无监督聚类问题