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

Android开发:如何在ListView中搜索多词语句而非单个单词

Android ListView多词语搜索解决方案

当前代码仅支持单个单词搜索,无法处理多词语句的搜索需求,以下是针对性的修复方案:

问题分析

现有代码将多词拆分为OR条件,导致只要包含任意一个关键词的条目都会被返回,而非匹配所有关键词;同时直接拼接SQL字符串存在注入风险,且空输入时未恢复原始列表。

修复步骤

1. 调整搜索逻辑(匹配所有关键词)

将原代码中的OR改为AND,确保只有包含所有搜索关键词的条目才会被筛选出来;若需要支持“包含任意关键词”,可保留OR。

2. 使用参数化查询避免SQL注入

直接拼接字符串存在安全风险,改用参数化查询绑定关键词。

3. 完善空输入处理

当搜索框为空时,恢复显示原始列表,提升用户体验。

4. 统一列表点击事件

避免重复设置OnItemClickListener,简化代码逻辑。

修改后的代码

MainActivity.java关键部分修改

etSearchKey.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        String search_by = "name";
        String key = etSearchKey.getText().toString().trim();
        
        // 空输入时恢复原始列表
        if (key.isEmpty()) {
            resetOriginalList();
            return;
        }

        String[] keys = key.split("\\s+");
        StringBuilder queryBuilder = new StringBuilder();
        // 构建AND条件的查询语句
        for (int i = 0; i < keys.length; i++) {
            if (i > 0) {
                queryBuilder.append(" AND ");
            }
            queryBuilder.append(search_by).append(" LIKE ?");
        }

        // 传递参数数组,避免SQL注入
        showResultOfSearch(queryBuilder.toString(), keys);
    }

    @Override
    public void afterTextChanged(Editable s) {}
});

// 新增恢复原始列表的方法
private void resetOriginalList() {
    String[] from = {"name"};
    int[] to = {R.id.row_hezb_name};
    SimpleAdapter adb = new SimpleAdapter(getBaseContext(), books_list, R.layout.row_hezb, from, to);
    contentListView.setAdapter(adb);
    // 绑定原始列表的点击事件
    contentListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent i = new Intent(getBaseContext(), List_hezbha.class);
            String my_id = books_list.get(position).get("name").toString();
            i.putExtra("name", my_id);
            startActivity(i);
        }
    });
}

// 修改showResultOfSearch方法,支持参数传递
public void showResultOfSearch(String query, String[] params) {
    db.open();
    contentListView.setAdapter(null);
    // 数据库方法改为接收查询语句和参数数组
    resultBooks = db.getTableOfResultsOfSearchhezb(query, params);
    db.close();

    if (resultBooks.size() < 1) {
        // 无结果时清空列表,也可添加空提示视图
        contentListView.setAdapter(null);
        return;
    }

    String[] from = {"name"};
    int[] to = {R.id.row_hezb_name};
    SimpleAdapter adb = new SimpleAdapter(getBaseContext(), resultBooks, R.layout.row_hezb, from, to);
    contentListView.setAdapter(adb);

    contentListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            try {
                etSearchKey.setText("");
                etSearchKey.clearFocus();
                Intent i = new Intent(getBaseContext(), List_hezbha.class);
                String my_id = resultBooks.get(position).get("name").toString();
                i.putExtra("name", my_id);
                startActivity(i);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    });
}

数据库类(database.java)对应修改

需要修改getTableOfResultsOfSearchhezb方法,支持参数化查询:

public List<HashMap<String, Object>> getTableOfResultsOfSearchhezb(String query, String[] params) {
    List<HashMap<String, Object>> list = new ArrayList<>();
    SQLiteDatabase db = this.getReadableDatabase();
    // 为每个参数添加通配符,实现模糊匹配
    String[] likeParams = new String[params.length];
    for (int i = 0; i < params.length; i++) {
        likeParams[i] = "%" + params[i] + "%";
    }
    // 使用rawQuery传递参数
    Cursor cursor = db.rawQuery("SELECT * FROM your_table_name WHERE " + query, likeParams);
    
    if (cursor.moveToFirst()) {
        do {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", cursor.getString(cursor.getColumnIndex("name")));
            // 其他字段按需添加
            list.add(map);
        } while (cursor.moveToNext());
    }
    cursor.close();
    return list;
}

额外优化建议

  • 添加搜索防抖:使用Handler延迟执行搜索逻辑,避免输入过程中频繁触发数据库查询。
  • 大小写不敏感搜索:在SQL语句中添加COLLATE NOCASE,实现忽略大小写的模糊匹配。

内容的提问来源于stack exchange,提问作者Shahin Sadeghi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:49:59