Android Volley ListView 闪烁和剩余项目
Android Volley ListView Blinking and Items Remaining
我有一个设置了 CustomAdapter
的 ListView
,它显示了一个 json 对象数组,我用 volley 请求调用这些对象:
final ListView listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapter(this,personList);
listView.setAdapter(adapter);
// Creating volley request obj
final JsonArrayRequest personReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
person.setfirstName(obj.getString("first_name"));
person.setlastName(obj.getString("last_name"));
//Add person to list
personList.add(person);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.i(TAG, "personList items: " + personList.size());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(personReq);
使用可运行对象和处理程序,我每 5 秒发出一次此请求:
//Run volley request every 5 seconds
Runnable runnable = new Runnable() {
@Override
public void run() {
if (orderList != null) {
orderList.clear();
}
//Placing here TOO removes the last item but causes blinking
//adapter.notifyDataSetChanged();
AppController.getInstance().addToRequestQueue(personReq);
handler.postDelayed(this, 5000);
}
};
handler.postDelayed(runnable, 5000);
问题是一个项目总是保留,即使它不应该存在(由于通过单独的截击请求将其删除)。点击该项目会导致应用程序崩溃,并显示 logcat 中的以下内容:
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.
如你所见,我正在调用 adapter.notifyDataSetChanged();添加一个人对象后直接。它工作正常,直到列表中的最后一项消失(但仍然可见)。
在 Runnable 中添加 adapter.notifyDataSetChanged();
会清除最后一项,但会导致整个视图每 5 秒闪烁一次。
甚至可以防止这种闪烁吗?
试试这个。
在您的适配器中。
public void addAll(List<T> datas) {
if (datas != null) {
mData.addAll(datas);
notifyDataSetChanged();
}
}
然后在你的 Activity.
personList.add(person);
adapter.addAll(personList);
adapter.notifyDataSetChanged();
确保您的适配器在其内容更改时调用 notifyDataSetChanged()
As you can see, I am calling adapter.notifyDataSetChanged(); directly
after adding a person object.
那太浪费了。调用notifyDataSetChanged
一次,在列表处于您要显示的最终状态后。
Adding adapter.notifyDataSetChanged(); inside the Runnable does clear
the last item but causes the whole view to blink every 5 seconds.
Is it even possible to prevent this blinking?
我只能猜测这 "blinking" 是因为您在发出网络请求之前清除列表并刷新适配器(从而使 ListView
为空),这当然会有一个根据网络情况延迟。
为什么不在发出网络请求之前清除您的列表,为什么不在响应返回后清除它?
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
personList.clear(); // Wipe the list before adding new data
// Parsing json
// The rest of your parsing code here...
// Now that the list is fully updated to the new state, call this ONCE
adapter.notifyDataSetChanged();
}
好的,我想出了一个停止闪烁和清除最后剩余项目的方法。
除了onResponse
方法之外,adapter.notifyDataSetChanged();
也必须存在于onErrorResponse
方法中。
我有一个设置了 CustomAdapter
的 ListView
,它显示了一个 json 对象数组,我用 volley 请求调用这些对象:
final ListView listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapter(this,personList);
listView.setAdapter(adapter);
// Creating volley request obj
final JsonArrayRequest personReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
person.setfirstName(obj.getString("first_name"));
person.setlastName(obj.getString("last_name"));
//Add person to list
personList.add(person);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.i(TAG, "personList items: " + personList.size());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(personReq);
使用可运行对象和处理程序,我每 5 秒发出一次此请求:
//Run volley request every 5 seconds
Runnable runnable = new Runnable() {
@Override
public void run() {
if (orderList != null) {
orderList.clear();
}
//Placing here TOO removes the last item but causes blinking
//adapter.notifyDataSetChanged();
AppController.getInstance().addToRequestQueue(personReq);
handler.postDelayed(this, 5000);
}
};
handler.postDelayed(runnable, 5000);
问题是一个项目总是保留,即使它不应该存在(由于通过单独的截击请求将其删除)。点击该项目会导致应用程序崩溃,并显示 logcat 中的以下内容:
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.
如你所见,我正在调用 adapter.notifyDataSetChanged();添加一个人对象后直接。它工作正常,直到列表中的最后一项消失(但仍然可见)。
在 Runnable 中添加 adapter.notifyDataSetChanged();
会清除最后一项,但会导致整个视图每 5 秒闪烁一次。
甚至可以防止这种闪烁吗?
试试这个。
在您的适配器中。
public void addAll(List<T> datas) {
if (datas != null) {
mData.addAll(datas);
notifyDataSetChanged();
}
}
然后在你的 Activity.
personList.add(person);
adapter.addAll(personList);
adapter.notifyDataSetChanged();
确保您的适配器在其内容更改时调用 notifyDataSetChanged()
As you can see, I am calling adapter.notifyDataSetChanged(); directly after adding a person object.
那太浪费了。调用notifyDataSetChanged
一次,在列表处于您要显示的最终状态后。
Adding adapter.notifyDataSetChanged(); inside the Runnable does clear the last item but causes the whole view to blink every 5 seconds.
Is it even possible to prevent this blinking?
我只能猜测这 "blinking" 是因为您在发出网络请求之前清除列表并刷新适配器(从而使 ListView
为空),这当然会有一个根据网络情况延迟。
为什么不在发出网络请求之前清除您的列表,为什么不在响应返回后清除它?
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
personList.clear(); // Wipe the list before adding new data
// Parsing json
// The rest of your parsing code here...
// Now that the list is fully updated to the new state, call this ONCE
adapter.notifyDataSetChanged();
}
好的,我想出了一个停止闪烁和清除最后剩余项目的方法。
除了onResponse
方法之外,adapter.notifyDataSetChanged();
也必须存在于onErrorResponse
方法中。