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

Android中如何将SQLite数据库数据加载至ListView?

SQLite数据加载至ListView重复显示问题

我尝试将SQLite数据库中的数据加载到ListView中,已完成fragment_history.xml布局、HistoryFragment.java逻辑、MyDatabaseHelper的fetchData查询方法以及ContactModel实体类,但目前ListView显示异常,打印Cursor到Logcat时发现内容重复,求解决。


相关代码

fragment_history.xml(包含ListView)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HistoryFragment">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/list_View"
        />

</LinearLayout>

HistoryFragment.java

public class HistoryFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_history, container, false);

        ListView lw = view.findViewById(R.id.list_View);
        MyDatabaseHelper myDB = new MyDatabaseHelper(getActivity());
        List<ContactModel> data = myDB.fetchData();
        ArrayAdapter<ContactModel> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, data);
        lw.setAdapter(adapter);

        return view;
    }

}

MyDatabaseHelper.java中的fetchData方法

public List<ContactModel> fetchData(){
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
    List<ContactModel> data = new ArrayList<ContactModel>();
    if(cursor.moveToFirst()){
        do {
            data.add(new ContactModel(cursor.getString(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4),cursor.getString(5)));
        }while(cursor.moveToNext());
    }
    cursor.close();
    return data;
}

ContactModel.java

public class ContactModel {
    private String id;
    private String weight;
    private String height;
    private String age;
    private String gender;
    private String bmi;

    public ContactModel(String id, String weight, String height, String age, String gender,String bmi) {
        this.id = id;
        this.weight = weight;
        this.height = height;
        this.age = age;
        this.gender = gender;
        this.bmi = bmi;
    }

    public String getID() {
        return this.id;
    }

    public String getWeight() {
        return this.weight;
    }

    public String getHeight() {
        return this.height;
    }

    public String getAge() {
        return this.age;
    }

    public String getGender() {
        return this.gender;
    }
    public String getBmi() {
        return this.bmi;
    }
}

当前问题表现

ListView显示内容重复,Logcat打印Cursor时也能看到重复数据。


问题排查与解决

1. 检查数据库插入逻辑(核心原因)

Cursor内容重复通常是数据插入时重复添加了相同记录,而非查询逻辑问题:

  • 检查MyDatabaseHelper的插入方法,避免在onCreate/onUpgrade中重复执行插入语句;
  • 插入数据前可通过唯一键判断记录是否存在,或使用INSERT OR IGNORE语句防止重复插入。

2. 优化查询数据读取逻辑

用列名而非硬编码索引获取Cursor数据,避免表结构变化导致的索引错误:

public List<ContactModel> fetchData(){
    SQLiteDatabase db = this.getReadableDatabase(); // 只读模式更高效
    Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
    List<ContactModel> data = new ArrayList<>();
    
    // 获取列索引,避免硬编码位置
    int idIndex = cursor.getColumnIndex("id");
    int weightIndex = cursor.getColumnIndex("weight");
    int heightIndex = cursor.getColumnIndex("height");
    int ageIndex = cursor.getColumnIndex("age");
    int genderIndex = cursor.getColumnIndex("gender");
    int bmiIndex = cursor.getColumnIndex("bmi");
    
    if(cursor.moveToFirst()){
        do {
            String id = cursor.getString(idIndex);
            String weight = cursor.getString(weightIndex);
            String height = cursor.getString(heightIndex);
            String age = cursor.getString(ageIndex);
            String gender = cursor.getString(genderIndex);
            String bmi = cursor.getString(bmiIndex);
            data.add(new ContactModel(id, weight, height, age, gender, bmi));
        }while(cursor.moveToNext());
    }
    cursor.close();
    return data;
}

3. 修复ListView显示逻辑

ArrayAdapter默认调用实体类的toString()显示内容,当前ContactModel未重写该方法,导致显示对象内存地址而非实际数据,可能被误判为重复。在ContactModel中添加:

@Override
public String toString() {
    return "ID: " + id + " | 体重: " + weight + " | BMI: " + bmi;
    // 可根据需求自定义显示格式
}

4. 验证Cursor真实数据

在fetchData中添加日志,打印每一条Cursor数据,确认数据库中是否真的存在重复记录:

if(cursor.moveToFirst()){
    do {
        Log.d("DB_DATA", "ID: " + cursor.getString(0) + ", Weight: " + cursor.getString(1));
        data.add(new ContactModel(cursor.getString(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4),cursor.getString(5)));
    }while(cursor.moveToNext());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:35:23