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

联系人APP搜索后点击列表项跳转显示错误数据问题排查

问题原因分析

你遇到的问题核心在于搜索过滤后,点击事件混用了原始联系人数组和过滤后列表的位置索引,两者完全不匹配:

  • 初始状态下,ListView展示的是原始数组arr的内容,点击时用position从arr取数据是正常的。
  • 但当你搜索过滤后,你创建了新的过滤列表listObjects并设置给了新的Adapter,此时ListView的每个item对应的position是过滤后列表的索引,可你点击时依然传递原始数组arr和这个position——这就导致用过滤后的索引去原始数组里取值,自然会拿到错误的联系人数据。
解决方案

我们需要保存当前ListView正在展示的列表,点击时从这个展示列表中获取对应位置的联系人,而不是依赖原始数组。同时优化数据传递方式,直接传递选中的联系人对象而非整个数组,更简洁高效。

步骤1:添加成员变量保存当前展示列表

在showAllContacts类中新增一个成员变量,用来记录当前ListView显示的联系人列表:

public class showAllContacts extends AppCompatActivity {
    String name, phone, mail;
    ArrayList<listObject> arr = new ArrayList<>();
    ListView listView;
    EditText search;
    ListAdapter adapter;
    private ArrayList<listObject> currentDisplayList; // 新增:保存当前展示的列表
    // ... 其他原有代码
}

步骤2:初始化当前展示列表

在onCreate方法中初始化ListView时,把原始数组赋值给currentDisplayList:

// get data from databse and put it in array
arr = dp.getAllRecords();
currentDisplayList = new ArrayList<>(arr); // 初始为原始列表
adapter = new ListAdapter(showAllContacts.this, R.layout.list_design, currentDisplayList);
listView.setAdapter(adapter);

步骤3:更新搜索过滤逻辑

在搜索的onTextChanged方法中,把过滤后的列表赋值给currentDisplayList:

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    int textlength = s.length();
    ArrayList<listObject> listObjects = new ArrayList<>();
    for (listObject c : arr) {
        if (textlength <= c.Name.length()) {
            if (c.Name.toLowerCase().contains(s.toString().toLowerCase())) {
                listObjects.add(c);
            }
        }
    }
    currentDisplayList = listObjects; // 更新当前展示列表
    adapter = new ListAdapter(showAllContacts.this, R.layout.list_design, currentDisplayList);
    listView.setAdapter(adapter);
}

步骤4:修改点击事件逻辑

点击时直接从currentDisplayList中获取选中的联系人对象,传递到下一个Activity:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Intent intent = new Intent(showAllContacts.this, userPage.class);
        // 获取当前展示列表中对应位置的联系人
        listObject selectedUser = currentDisplayList.get(position);
        // 直接传递选中的对象(确保listObject已经实现Serializable接口)
        intent.putExtra("selectedUser", selectedUser);
        startActivity(intent);
    }
});

步骤5:在userPage中接收数据

在userPage类中,直接获取传递过来的联系人对象即可:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_user_page);
    
    listObject selectedUser = (listObject) getIntent().getSerializableExtra("selectedUser");
    // 然后使用selectedUser中的name、phone、mail等数据展示即可
}
额外优化建议
  • 可以考虑使用Android原生的Filter接口来实现列表过滤,而不是每次创建新的Adapter,这样性能更好,代码也更规范。
  • 避免在onCreate中盲目捕获NullPointerException和通用Exception,这会掩盖潜在的错误,不利于调试。

内容的提问来源于stack exchange,提问作者M.fouad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:33:06