为什么 ArrayAdapter 在 activity 重启后无法更新列表视图?
Why does ArrayAdapter fail to update listview after activity restart?
我有一个 activity,它在 onCreate() 中执行以下操作:
- 创建一个空的 ArrayList
- 创建一个与上述 ArrayList 关联的新 ArrayAdapter
- 设置 ListView 使用上面的 ArrayAdapter
- 使用 Volley 向我的 API 发送 GET 请求以获取一些 JSON 数据以加载到 ListView
获取数据后,我将其添加到我的 ArrayList 并按预期填充 ListView
我的问题是当 activity 重新启动时(即通过模拟器旋转屏幕或通过 Android Studio 重新启动 activity)ListView 不再填充。
我没有保存任何状态。我希望 activity 到 return 到其初始默认状态,所以我认为 onSaveInstanceState() 不是答案。
我已验证数据已从 API 成功 returned 并且适配器的哈希码在 volley 请求之前和之后相同,并且它等于 ListView 的设置适配器。我还验证了当 activity 重新启动时会调用 onDestroy() 和 onCreate() ,所以我知道它正在经历一个完整的生命周期。
如果我使用 setRequestedOrientation() 以编程方式旋转屏幕,我不会遇到此问题。如果我在 GET 请求回调之外向我的 ArrayList 添加项目,我不会遇到此问题。
这是我的 activity onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
//The data to be displayed
descriptions = new ArrayList<>();
listView = (ListView)this.findViewById(R.id.myListView);
//Link 'descriptions' to the adapter
adapter = new ArrayAdapter<>(this, R.layout.list_json_text_view, descriptions);
listView.setAdapter(adapter);
this.addTextFilter();
this.addListViewClickListener();
//See my ApiGetRequest class below
request = new ApiGetRequest();
request.send(this.getContext(), getDataUrl(), this, "", REQUEST_TYPES.TEXT);
}
还有我的activity GET 请求回调
public void onSuccess(DescriptiveJSONArray items, REQUEST_TYPES type) {
descriptions.clear();
try {
for (int i = 0; i < items.length(); ++i) {
JSONObject obj = items.getJSONObject(i);
String desc = obj.optString("name", "") + " " + obj.optString("description", "");
//TODO: Remove debug code
System.out.println("Adding: "+desc);
descriptions.add(desc);
}
}
catch(JSONException e) {
e.printStackTrace();
//getJSONObject failed
}
}
还有我的 ApiGetRequest 方法
//My activity implements ApiGetCallback
public void send(Context context, String url, ApiGetCallback callback, String tag, REQUEST_TYPES type) {
StringRequest stringRequest = getStringRequest(url, callback, tag, type);
//Singleton wrapper for RequestQueue
AppRequestQueue queue = AppRequestQueue.getInstance(context);
queue.add(stringRequest);
}
//Inner class inside ApiGetCallback
class SuccessListener implements Response.Listener<String> {
ApiGetCallback callback;
REQUEST_TYPES type;
public SuccessListener(ApiGetCallback callback, REQUEST_TYPES type) {
this.callback = callback;
this.type = type;
}
@Override
public void onResponse(String response) {
try {
DescriptiveJSONArray jsonResp = new DescriptiveJSONArray(response);
callback.onSuccess(jsonResp, type);
}
catch(JSONException e) {
callback.onJsonException(e);
}
}
}
知道发生了什么吗?我正在测试 Marshmallow 和 Nougat
在 onSuccess 函数完成后,您缺少对 notifyDataSetChanged
的调用。
adapter = new ArrayAdapter<>(this, R.layout.list_json_text_view, descriptions);
listView.setAdapter(adapter);
//See my ApiGetRequest class below
request = new ApiGetRequest();
request.send(this.getContext(), getDataUrl(), this, "", REQUEST_TYPES.TEXT);
在onResume方法中使用这部分代码。
您可能需要覆盖 onStart 并更新其中的任何内容
我有一个 activity,它在 onCreate() 中执行以下操作:
- 创建一个空的 ArrayList
- 创建一个与上述 ArrayList 关联的新 ArrayAdapter
- 设置 ListView 使用上面的 ArrayAdapter
- 使用 Volley 向我的 API 发送 GET 请求以获取一些 JSON 数据以加载到 ListView
获取数据后,我将其添加到我的 ArrayList 并按预期填充 ListView
我的问题是当 activity 重新启动时(即通过模拟器旋转屏幕或通过 Android Studio 重新启动 activity)ListView 不再填充。
我没有保存任何状态。我希望 activity 到 return 到其初始默认状态,所以我认为 onSaveInstanceState() 不是答案。
我已验证数据已从 API 成功 returned 并且适配器的哈希码在 volley 请求之前和之后相同,并且它等于 ListView 的设置适配器。我还验证了当 activity 重新启动时会调用 onDestroy() 和 onCreate() ,所以我知道它正在经历一个完整的生命周期。
如果我使用 setRequestedOrientation() 以编程方式旋转屏幕,我不会遇到此问题。如果我在 GET 请求回调之外向我的 ArrayList 添加项目,我不会遇到此问题。
这是我的 activity onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
//The data to be displayed
descriptions = new ArrayList<>();
listView = (ListView)this.findViewById(R.id.myListView);
//Link 'descriptions' to the adapter
adapter = new ArrayAdapter<>(this, R.layout.list_json_text_view, descriptions);
listView.setAdapter(adapter);
this.addTextFilter();
this.addListViewClickListener();
//See my ApiGetRequest class below
request = new ApiGetRequest();
request.send(this.getContext(), getDataUrl(), this, "", REQUEST_TYPES.TEXT);
}
还有我的activity GET 请求回调
public void onSuccess(DescriptiveJSONArray items, REQUEST_TYPES type) {
descriptions.clear();
try {
for (int i = 0; i < items.length(); ++i) {
JSONObject obj = items.getJSONObject(i);
String desc = obj.optString("name", "") + " " + obj.optString("description", "");
//TODO: Remove debug code
System.out.println("Adding: "+desc);
descriptions.add(desc);
}
}
catch(JSONException e) {
e.printStackTrace();
//getJSONObject failed
}
}
还有我的 ApiGetRequest 方法
//My activity implements ApiGetCallback
public void send(Context context, String url, ApiGetCallback callback, String tag, REQUEST_TYPES type) {
StringRequest stringRequest = getStringRequest(url, callback, tag, type);
//Singleton wrapper for RequestQueue
AppRequestQueue queue = AppRequestQueue.getInstance(context);
queue.add(stringRequest);
}
//Inner class inside ApiGetCallback
class SuccessListener implements Response.Listener<String> {
ApiGetCallback callback;
REQUEST_TYPES type;
public SuccessListener(ApiGetCallback callback, REQUEST_TYPES type) {
this.callback = callback;
this.type = type;
}
@Override
public void onResponse(String response) {
try {
DescriptiveJSONArray jsonResp = new DescriptiveJSONArray(response);
callback.onSuccess(jsonResp, type);
}
catch(JSONException e) {
callback.onJsonException(e);
}
}
}
知道发生了什么吗?我正在测试 Marshmallow 和 Nougat
在 onSuccess 函数完成后,您缺少对 notifyDataSetChanged
的调用。
adapter = new ArrayAdapter<>(this, R.layout.list_json_text_view, descriptions);
listView.setAdapter(adapter);
//See my ApiGetRequest class below
request = new ApiGetRequest();
request.send(this.getContext(), getDataUrl(), this, "", REQUEST_TYPES.TEXT);
在onResume方法中使用这部分代码。
您可能需要覆盖 onStart 并更新其中的任何内容