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

ListView按bairro字段过滤功能实现问题求助

排查ListView按“bairro”字段过滤异常的问题

你已经折腾ListView的过滤功能好一阵子了,程序没报错但就是不生效,而且列表还得保留只显示状态为PROGRAMADA、日期为当天且属于当前用户的记录,我仔细看了你的代码,发现几个关键问题,咱们一个个来解决:


首先看Activity里的核心问题:每次文本变化都新建Adapter,未复用绑定实例

你在onTextChanged里每次都new了一个OrdemServicoAdapter,然后调用它的filter,但这个新Adapter根本没和你的ListView绑定,过滤后的结果自然不会显示在界面上。正确的做法是把初始设置的Adapter保存为Activity成员变量,直接调用这个实例的filter方法。

修复后的Activity代码片段:

// 把Adapter定义为Activity的成员变量
private OrdemServicoAdapter osAdapter;

public void getOSProgramada(){ 
    final ArrayList<OrdemServico> lstOsProgramada = new ArrayList<>(); 
    if(ordem_servicoSerializado.exists()){ 
        try { 
            ArrayList<OrdemServico> lstOS = (ArrayList<OrdemServico>) new SerializarDados().restauraDadosemArquivo(config.sARMAZENAMENTO_ARQUIVO_LOCAL, "ordem_servico"); 
            Usuario usu = (Usuario) new SerializarDados().restauraDadosemArquivo(config.sARMAZENAMENTO_ARQUIVO_LOCAL, "usuario"); 
            for(int i = 0; i < lstOS.size(); i++){ 
                if(lstOS.get(i).getNid_usuario() == usu.getNid_usuario() && lstOS.get(i).getSstatus().equals("PROGRAMADA") && lstOS.get(i).getSdata_programada().equals(""+config.getDataAtual())){ 
                    OrdemServico os = new OrdemServico(); 
                    // 原有赋值代码保持不变,此处省略
                    lstOsProgramada.add(os); 
                } 
            } 
            // 初始化Adapter并保存为成员变量,同时绑定到ListView
            osAdapter = new OrdemServicoAdapter(MenuPrincipalActivity.this, lstOsProgramada);
            setListAdapter(osAdapter); 

            EditText editText = (EditText) findViewById(R.id.editText1); 
            editText.addTextChangedListener(new TextWatcher() { 
                public void onTextChanged(CharSequence s, int start, int before, int count) { 
                    // 直接调用已绑定的Adapter执行过滤
                    osAdapter.getFilter().filter(s.toString()); 
                } 

                @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} 
                @Override public void afterTextChanged(Editable s) {} 
            }); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 
}

然后是Adapter Filter的三个致命错误

你的Filter逻辑里有几个严重问题,直接导致过滤失效:

  1. 重复读取本地文件:每次过滤都重新读取全部数据,不仅效率低,还没应用初始过滤规则(PROGRAMADA、当天日期、当前用户),会把不符合要求的记录也纳入过滤范围;
  2. 添加空对象:循环里创建了空的OrdemServico os = new OrdemServico();然后添加到列表,过滤后的结果全是空对象,没有有效数据;
  3. 变量名错误:最后给results赋值时用了lista.size()和lista,但此处应该用你创建的lstOsProgramada,变量名不匹配导致结果为空。

修复后的Adapter Filter代码:

// 给Adapter添加成员变量,保存初始过滤后的原始数据源
private ArrayList<OrdemServico> originalList;
private ArrayList<OrdemServico> filteredList;

// 在Adapter构造方法里初始化这两个列表
public OrdemServicoAdapter(Context context, ArrayList<OrdemServico> data) {
    // 原有构造代码保持不变
    originalList = new ArrayList<>(data);
    filteredList = new ArrayList<>(data);
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence filtro) {
            FilterResults results = new FilterResults();
            filteredList.clear();

            if (filtro == null || filtro.length() == 0) {
                // 无过滤条件时,直接返回原始已筛选列表
                filteredList.addAll(originalList);
            } else {
                String filterStr = filtro.toString().toUpperCase();
                // 仅在已符合初始规则的列表中过滤
                for (OrdemServico os : originalList) {
                    String bairro = os.getSbairro().toUpperCase();
                    if (bairro.contains(filterStr)) {
                        filteredList.add(os);
                    }
                }
            }

            results.count = filteredList.size();
            results.values = filteredList;
            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            // 更新Adapter数据源并通知界面刷新
            lista = (ArrayList<OrdemServico>) results.values;
            notifyDataSetChanged();
        }
    };
}

修复思路总结

  1. 复用Adapter实例:确保过滤操作在已绑定到ListView的Adapter上执行,避免新建无效实例;
  2. 保留初始过滤规则:用Adapter保存好已筛选的PROGRAMADA、当天日期的记录,过滤时仅在这个子集里操作,无需重复读取本地文件;
  3. 修正对象引用:直接添加原始列表中的有效对象,避免创建空对象导致无数据;
  4. 修复变量名错误:确保results赋值的是正确的过滤后列表。

这样修改后,按“bairro”字段的过滤功能应该就能正常工作,同时也保留了你原来的固定过滤规则。

内容的提问来源于stack exchange,提问作者Israyane Nayara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:25:02