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

如何修复Android中adapter.notifyDataSetChanged()无法生效的问题

解决adapter.notifyDataSetChanged()无法刷新ListView的问题

咱们先拆解代码里的几个核心问题,这些问题直接导致刷新方法失效:

1. 适配器与数据源不匹配且未正确关联

你的代码里存在两个完全独立的数据源:

  • showEmployee()里用的是ArrayList<HashMap<String,String>>作为SimpleAdapter的数据源
  • cariData()里操作的是成员变量List<DataModel> listData
    同时,成员变量adapter从未被正确赋值——showEmployee()里创建的是局部ListAdapter,和成员变量adapter完全没关系,所以调用adapter.notifyDataSetChanged()时,要么是null,要么不是ListView正在使用的适配器。

2. 刷新时机错误

在cariData()里,你先调用了adapter.notifyDataSetChanged()再往listData里添加数据,这时候数据源还是空的,刷新自然不会有效果。


具体修复步骤

第一步:统一数据源与适配器

首先,咱们把所有数据源统一为List<DataModel>,并自定义一个适配DataModel的适配器(替代原来的SimpleAdapter):

// 自定义适配器类,可放在SemuaData类内部或单独文件中
private class DataAdapter extends BaseAdapter {
    private Context context;
    private List<DataModel> dataList;

    public DataAdapter(Context context, List<DataModel> dataList) {
        this.context = context;
        this.dataList = dataList;
    }

    @Override
    public int getCount() {
        return dataList.size();
    }

    @Override
    public Object getItem(int position) {
        return dataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
        }
        DataModel data = dataList.get(position);
        // 绑定数据到布局控件
        TextView tvId = convertView.findViewById(R.id.id);
        TextView tvNama = convertView.findViewById(R.id.nama);
        tvId.setText(data.getId());
        tvNama.setText(data.getNama());
        return convertView;
    }
}

第二步:修改showEmployee()方法,统一数据源与适配器

把原来的HashMap数据源替换成listData,并初始化成员变量adapter:

private void showEmployee(){
    JSONObject jsonObject = null;
    listData.clear(); // 先清空旧数据
    try {
        jsonObject = new JSONObject(JSON_STRING);
        JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY);
        for(int i = 0; i<result.length(); i++){
            JSONObject jo = result.getJSONObject(i);
            DataModel data = new DataModel();
            data.setId(jo.getString(Config.TAG_ID));
            data.setNama(jo.getString(Config.TAG_NAMA));
            data.setUmur(jo.getString(Config.TAG_UMUR));
            data.setAlamat(jo.getString(Config.TAG_ALAMAT));
            listData.add(data);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    // 初始化成员变量adapter,绑定到ListView
    adapter = new DataAdapter(this, listData);
    list_view.setAdapter(adapter);
}

第三步:修正cariData()方法的逻辑顺序

先更新数据源,再调用刷新方法,同时确保操作的是同一个listData和adapter:

private void cariData(final String keyword) {
    StringRequest strReq = new StringRequest(Request.Method.POST, Config.url_cari,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.e("DATA RESPONSE SEARCH : ", response.toString());
                    try {
                        JSONObject jObj = new JSONObject(response);
                        int value = jObj.getInt(TAG_VALUE);
                        if (value == 1) {
                            listData.clear(); // 清空旧数据
                            String getObject = jObj.getString(TAG_RESULTS);
                            JSONArray jsonArray = new JSONArray(getObject);
                            for (int i = 0; i < jsonArray.length(); i++) {
                                JSONObject obj = jsonArray.getJSONObject(i);
                                DataModel data = new DataModel();
                                data.setId(obj.getString(TAG_ID));
                                data.setNama(obj.getString(TAG_NAMA));
                                data.setUmur(obj.getString(TAG_UMUR));
                                data.setAlamat(obj.getString(TAG_ALAMAT));
                                listData.add(data);
                            }
                            // 数据源更新完成后再刷新
                            adapter.notifyDataSetChanged();
                        } else {
                            Toast.makeText(getApplicationContext(), jObj.getString(TAG_MESSAGE), Toast.LENGTH_SHORT).show();
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.e(TAG, "Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("keyword", keyword);
            return params;
        }
    };
    AppController.getInstance().addToRequestQueue(strReq, tag_json_obj);
}

第四步:修正成员变量声明

确保成员变量adapter的类型是咱们自定义的DataAdapter:

// 替换原来的Adapter adapter;
private DataAdapter adapter;

额外优化建议

  • 可以在onQueryTextChange()里实现实时搜索逻辑,提升用户体验:
@Override
public boolean onQueryTextChange(String newText) {
    if (TextUtils.isEmpty(newText)) {
        // 输入为空时重新加载全部数据
        getJSON();
    } else {
        cariData(newText);
    }
    return true;
}
  • 注意Volley的onResponse已经在主线程执行,所以直接调用notifyDataSetChanged()是安全的,其他异步操作要确保在主线程更新UI。

内容的提问来源于stack exchange,提问作者Rijal Khalik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:43:53