刷新adapte要注意的地方,和adapter使用的流程

简介: 刷新adapte要注意的地方,和adapter使用的流程

一般情况下,使用adapte的具体步骤如下:


1,new对象

2,添加adapter

3,然后请求数据,

4,设置数据。

5,通知adapter数据发生改变,进行刷新。


如果有再次请求,则是:

1,先请求数据,

2,删除原来的数据,

3,添加请求到的数据,

4,对数据进行刷新。


刚遇到的一个错误,


使用的流程是就是:

1,删除数据,

2,请求数据,

3,然后添加数据,

4,刷新数据


代码如下:


public static void request() {
    list.clear();
    String url = "http://192.168.1.103:8080/sxpitransportation/intersection/findIntersectionByIid.do";
    for (int i = 0; i < 5; i++) {
        http_lv.get(url + "?iid=" + (i + 1), new Http_lv.Onreqeut() {
            @Override
            public void on(String s) {
                Log.e(""+Thread.currentThread().getName(), "on: "+s );
                try {
                    JSONObject object = new JSONObject(s);
                    String string = object.optString("msg");
                    object = new JSONObject(string);
                    A11_Baen baen = new A11_Baen(object.optInt("iid"),
                            object.optInt("red"), object.optInt("green"),
                            object.optInt("yellow"));
                    list.add(baen);
                    if (list.size() == 5) {
                        adapter.notifyDataSetChanged();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}


就是先清空数据源,然后请求到数据后对adapter的数据源进行添加数据,然后刷新adapter

报的错误如下所示:


java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131165215, class android.widget.ListView) with Adapter(class com.laohu.cn.A11$5)]
        at android.widget.ListView.layoutChildren(ListView.java:1618)


翻译如下:


适配器的内容已经更改,但ListView没有收到通知。

确保适配器的内容不是从后台线程修改的,

而是只从UI线程修改的。确保适配器在其内容更改时调用notifyDataSetChanged()。


原因应该就是在请求数据之前清空了数据,然后才进行网络请求,在请求的过程中,listview发现数据源已经发生变化,但是并没有通知说数据源发生了变化,所以才导致了这个异常。


修改如下:


public static void request() {
    String url = "http://192.168.1.103:8080/sxpitransportation/intersection/findIntersectionByIid.do";
    for (int i = 0; i < 5; i++) {
        http_lv.get(url + "?iid=" + (i + 1), new Http_lv.Onreqeut() {
            @Override
            public void on(String s) {
                Log.e(""+Thread.currentThread().getName(), "on: "+s );
                try {
                    JSONObject object = new JSONObject(s);
                    String string = object.optString("msg");
                    object = new JSONObject(string);
                    A11_Baen baen = new A11_Baen(object.optInt("iid"),
                            object.optInt("red"), object.optInt("green"),
                            object.optInt("yellow"));
                    temp.add(baen);
                    if (temp.size() == 5) {
                        list.clear();
                        list.addAll(temp);
                        temp.clear();
                        adapter.notifyDataSetChanged();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}


创建一个全局变临时集合temp存储请到的数据。首先请求到数据后,第一步就是清掉数据源,然后添加请求到的数据到数据源,然后清空temp,最后刷新适配器就好了。


还有一种做法就是,数据源发生变化之后立即对适配器进行刷新。代码如下:


public static void request() {
    list.clear();
    adapter.notifyDataSetChanged();
    String url = "http://192.168.1.103:8080/sxpitransportation/intersection/findIntersectionByIid.do";
    for (int i = 0; i < 5; i++) {
        http_lv.get(url + "?iid=" + (i + 1), new Http_lv.Onreqeut() {
            @Override
            public void on(String s) {
                Log.e(""+Thread.currentThread().getName(), "on: "+s );
                try {
                    JSONObject object = new JSONObject(s);
                    String string = object.optString("msg");
                    object = new JSONObject(string);
                    A11_Baen baen = new A11_Baen(object.optInt("iid"),
                            object.optInt("red"), object.optInt("green"),
                            object.optInt("yellow"));
                    list.add(baen);
                    if (list.size() == 5) {
                       /* list.clear();
                        list.addAll(temp);
                        temp.clear();*/
                        adapter.notifyDataSetChanged();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}


我在刚开始清除了数据源,然后立即进行刷新,最后在进行网络请求,拿到数据后给数据源,在刷新一次。这样也可以。


总结一下:无非就是在数据源发生变化的时候必须立即对adapter进行刷新。而我上面就是数据源发生变化了,但是并没有对其进行刷新,跟着请求了数据,然后才刷新。在这个过程中刷新是在网络请求结束后操作的,所以会有一定的耗时,结果I就导致了异常。我上面写了两种解决的办法,第一种是请求到数据之后才清空数据源,对其进行刷新。这样好处就是如果网络请求失败,并不会更改数据源。

但是第二种就是直接清空,在刷新,在网络请求。这样就导致网络请求失败后数据源被清空了,界面上就没有要显示的东西了。


如有错误,还请指出,谢谢!


相关文章
|
9月前
|
Java Android开发
Android系统 获取用户最后操作时间回调实现和原理分析
Android系统 获取用户最后操作时间回调实现和原理分析
254 0
|
9月前
|
IDE 测试技术 开发工具
Poco1.0.87新增的节点刷新接口:refresh()
Poco1.0.87新增的节点刷新接口:refresh()
126 1
jira学习案例62-userState的懒初始化和保存函数状态2
jira学习案例62-userState的懒初始化和保存函数状态2
56 0
jira学习案例62-userState的懒初始化和保存函数状态2
jira学习案例63-userState的懒初始化和保存函数状态3
jira学习案例63-userState的懒初始化和保存函数状态3
218 0
jira学习案例63-userState的懒初始化和保存函数状态3
|
JavaScript 索引
面试题分享,修改数据无法更新UI
面试题分享,修改数据无法更新UI
142 0
面试题分享,修改数据无法更新UI
|
存储 缓存 算法
更高效地刷新 RecyclerView | DiffUtil二次封装
每次数据变化都全量刷新整个列表是很奢侈的,不仅整个列表会闪烁一下,而且所有可见表项都会重新绑定一遍数据。这一篇对 DiffUtil 进行二次封装以让其更易于使用。
610 0
|
存储 缓存 算法
读源码长知识 | 更好的 RecyclerView 表项点击监听器
RecyclerView没有提供表项点击事件监听器,只能自己处理。这一篇介绍一种更加解耦,更易于使用的表项点击事件监听方法。
235 0
SwiftUI—如何实现对视图显示和消失事件的监听
SwiftUI—如何实现对视图显示和消失事件的监听
724 0
SwiftUI—如何实现对视图显示和消失事件的监听
|
前端开发
前端工作小结93-重置逻辑
前端工作小结93-重置逻辑
100 0
|
前端开发
前端工作小结79-重置逻辑
前端工作小结79-重置逻辑
104 0