RecyclerView不显示问题:API数据填充搜索建议列表失败
问题分析与解决方案
核心错误点
- 错误创建Activity实例:在
FetchStock中通过new MainActivity()获取实例,这是全新的Activity对象,并非当前显示的MainActivity,导致数据无法添加到RecyclerView绑定的ArrayList中。 - 未通知适配器数据更新:即使数据正确添加到ArrayList,RecyclerView也不会自动刷新,必须调用适配器的
notifyDataSetChanged()方法。 - 未清空旧数据:每次输入变化发起请求后,旧的搜索结果没有被清除,会导致列表内容重复累加。
- 无空输入判断:输入框为空时仍发起API请求,造成无效请求。
修正步骤及代码示例
1. 重构FetchStock,使用接口回调传递数据
避免直接创建Activity实例,通过接口将请求结果回调给MainActivity:
public class FetchStock extends AsyncTask<String, Void, String> { private static final String TAG = FetchStock.class.getSimpleName(); private OnDataLoadedListener listener; // 定义回调接口 public interface OnDataLoadedListener { void onDataLoaded(List<stockSuggestionModel> data); } public FetchStock(OnDataLoadedListener listener) { this.listener = listener; } @Override protected String doInBackground(String... params) { // 此处编写网络请求逻辑,返回API返回的JSON字符串 String jsonResponse = ""; // ... 省略网络请求代码 return jsonResponse; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); ArrayList<stockSuggestionModel> dataList = new ArrayList<>(); if (s == null || s.isEmpty()) { listener.onDataLoaded(dataList); return; } try { JSONObject jsonObject = new JSONObject(s); JSONArray data = jsonObject.getJSONArray("data"); for (int i = 0; i < data.length(); i++) { JSONObject itemsArray = data.getJSONObject(i); // 使用optString避免字段不存在时抛出异常 String symbol = itemsArray.optString("symbol"); String instrument_name = itemsArray.optString("instrument_name"); if (!symbol.isEmpty() && !instrument_name.isEmpty()) { stockSuggestionModel model = new stockSuggestionModel(); model.setStockName(instrument_name); model.setStockSymbol(symbol); dataList.add(model); } } } catch (Exception e) { e.printStackTrace(); } listener.onDataLoaded(dataList); } }
2. 修改MainActivity逻辑,处理回调并刷新列表
实现回调接口,添加空输入判断,取消重复请求:
public class MainActivity extends AppCompatActivity implements FetchStock.OnDataLoadedListener { private static final String TAG = MainActivity.class.getSimpleName(); private EditText et_DataInput; RecyclerView recyclerView; ArrayList<stockSuggestionModel> stockSuggestionList; stockSuggestAdapter suggestAdapter; private FetchStock currentFetchTask; // 用于取消未完成的请求 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_DataInput = findViewById(R.id.et_inputData); stockSuggestionList = new ArrayList<>(); recyclerView = findViewById(R.id.searchSuggestion); suggestAdapter = new stockSuggestAdapter(this, stockSuggestionList); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(suggestAdapter); et_DataInput.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { String queryString = s.toString().trim(); Log.i(TAG, "Search: " + queryString); // 取消之前未完成的请求,避免结果乱序 if (currentFetchTask != null && currentFetchTask.getStatus() != AsyncTask.Status.FINISHED) { currentFetchTask.cancel(true); } // 空输入时清空列表 if (queryString.isEmpty()) { stockSuggestionList.clear(); suggestAdapter.notifyDataSetChanged(); return; } // 发起新请求 currentFetchTask = new FetchStock(MainActivity.this); currentFetchTask.execute(queryString); } @Override public void afterTextChanged(Editable s) { } }); } @Override public void onDataLoaded(List<stockSuggestionModel> data) { // 清空旧数据,添加新数据并刷新适配器 stockSuggestionList.clear(); stockSuggestionList.addAll(data); suggestAdapter.notifyDataSetChanged(); } }
3. 可选:优化适配器封装性
在适配器中添加数据更新方法,简化MainActivity逻辑:
public class stockSuggestAdapter extends RecyclerView.Adapter<stockSuggestAdapter.viewHolder> { Context context; ArrayList<stockSuggestionModel> stockSuggestionArrayList; public stockSuggestAdapter(Context context, ArrayList<stockSuggestionModel> stockSuggestionArrayList) { this.context = context; this.stockSuggestionArrayList = stockSuggestionArrayList; } // 添加统一更新数据的方法 public void updateData(List<stockSuggestionModel> newData) { stockSuggestionArrayList.clear(); stockSuggestionArrayList.addAll(newData); notifyDataSetChanged(); } // ... 原有onCreateViewHolder、onBindViewHolder、getItemCount代码不变 }
此时MainActivity的onDataLoaded可简化为:
@Override public void onDataLoaded(List<stockSuggestionModel> data) { suggestAdapter.updateData(data); }
额外建议
- 添加请求防抖(比如延迟500ms再发起请求),减少频繁输入时的API调用次数
- 考虑使用Coroutines或Retrofit替代AsyncTask(AsyncTask已被标记为废弃)
- 对网络请求添加异常处理和加载状态提示
内容的提问来源于stack exchange,提问作者Prateek
相关产品推荐
相关产品推荐

