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

Android正确实现SearchView 解决ListView过滤后点击跳转错误

问题根因
  • 核心逻辑错误:点击事件硬编码用列表当前显示位置position匹配原始地点数组索引。SearchView触发过滤后,ArrayAdapter仅展示符合搜索条件的条目子集,此时回调的position是过滤后列表的位置,和原始数组的索引完全不匹配。比如搜索"Fourth Location"时,列表仅展示这1个条目,它在过滤后列表的position为0,代码判断position==0就会跳转第一个地点的坐标,必然出错。
  • 语法隐患:原有代码最后一个if条件块缺少闭合右括号,编译阶段就可能报错。
  • 细节问题:原有geo协议URI里geo:后多了空格,部分设备会解析失败。
修复步骤

1. 定义实体类绑定地点名称和坐标

不要分开维护名称数组、硬编码坐标判断,把每个地点的名称、对应跳转URI绑定成一个对象,从根源避免索引错位:

public class LocationItem {
    private String name;
    private String geoUri;

    public LocationItem(String name, String geoUri) {
        this.name = name;
        this.geoUri = geoUri;
    }

    public String getName() {
        return name;
    }

    public String getGeoUri() {
        return geoUri;
    }

    // 重写toString,让ArrayAdapter默认显示地点名称
    @Override
    public String toString() {
        return name;
    }
}

2. 替换原有字符串数组,用实体列表初始化适配器

把原来的字符串数组成员替换成实体列表,初始化时把每个地点的名称、坐标一一对应:

// 替换Activity里的原有成员变量定义
ListView listView;
List<LocationItem> locationList = new ArrayList<>();
ArrayAdapter<LocationItem> arrayAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // 省略原有ActionBar、setContentView相关代码...

    listView = findViewById(R.id.listview);
    // 初始化地点数据
    locationList.add(new LocationItem("First Location", "geo:21.422458,39.826213"));
    locationList.add(new LocationItem("Second Location", "geo:24.467275,39.610629"));
    locationList.add(new LocationItem("Third Location", "geo:25.173059,45.142079"));
    locationList.add(new LocationItem("Fourth Location", "geo:26.348400,43.766664"));

    arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, locationList);
    listView.setAdapter(arrayAdapter);

3. 重写点击事件逻辑,废弃硬编码位置判断

点击时直接从适配器当前显示的列表里取对应条目,不管过滤前后列表怎么变,都能拿到当前点击项的正确坐标:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            LocationItem clickedItem = (LocationItem) parent.getItemAtPosition(position);
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(clickedItem.getGeoUri()));
            startActivity(intent);
        }
    });
// 补全onCreate方法的闭合括号
}

搜索过滤的逻辑不用改,原有arrayAdapter.getFilter().filter(newText)可以正常工作。

修复原理

ArrayAdapter执行过滤时,会把符合搜索条件的条目单独存到内部的临时显示列表,点击事件返回的position永远对应当前屏幕展示的过滤后列表位置,和原始全量数据列表的索引没有绑定关系。直接通过getItemAtPosition(position)取当前展示的条目对象,不依赖硬编码的索引映射,无论怎么搜索过滤,都能拿到用户实际点击的地点数据,不会再出现跳转错位的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:09:25