You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:47:15