【问题标题】:Android: setListAdapter sets only last row in databaseAndroid:setListAdapter 仅设置数据库中的最后一行
【发布时间】:2011-04-06 17:59:12
【问题描述】:

正如标题所述,我在将数据从数据库链接到列表视图时遇到了一点问题,问题在于适配器将只设置返回的最后一行,而不是数据库表中的每一行。

我正在努力实现的一个例子:

餐桌动物: 猴 猫 狗 老虎

将在屏幕上仅显示为 Tiger。

我的方法从数据库返回游标:

public Cursor retrieveAnimals(){

    return = DB.query(ANIMAL_TABLE, new String[] {
            KEY_ROWID,
            KEY_ANIMALNAME,
            },
            null,
            null,
            null,
            null,
            null);      
}

并设置列表视图

    dbm = new MyDBManager(this);
    dbm.open();
    dbm.deleteAnimals();
    dbm.populateDB();

    // after populating, set the adapter..
    myCursor = dbm.getAllAnimals();

String[] columns = new String[] {"animal_name"};
int[] to = new int[] {R.id.animal};

SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.row, myCursor, columns, to);
    this.setListAdapter(mAdapter);

我感觉我的问题在于光标位置,因为在设置适配器时它会自动移动到最后一行,我一直在尝试找到解决问题的方法,但没有成功。

提前感谢您的任何建议。

编辑:填充数据库的方法

public long populateDB(){


    ContentValues initialValues = new ContentValues();

    for(int i = 0; i < animalName.length; i++){
        initialValues.put(KEY_ANIMALNAME, animalName[i]);
    }

    return DB.insert(ANIMAL_TABLE, null, initialValues);

}

【问题讨论】:

  • myCursor.getCount() 返回什么?

标签: android database listview adapter


【解决方案1】:

在您的retrieveAnimals() 中,该行应为return DB.query(...)(注意returnDB.query 之间缺少=)。

除此之外,您的代码看起来还不错。您应该在光标上调用startManagingCursor(在调用getAllAnimals 之后)以避免内存泄漏。

编辑:将您的填充方法更改为:

public long[] populateDB(){


    ContentValues initialValues = new ContentValues();
    long[] rowIds = new long[animalName.length];

    for(int i = 0; i < animalName.length; i++){
        // here we are using a single ContentValues object and inserting it
        // into the DB before changing the ContentValues and inserting it again
        initialValues.put(KEY_ANIMALNAME, animalName[i]);
        rowIds[i] = DB.insert(ANIMAL_TABLE, null, initialValues);
    }

    return rowIds;

}

或者(更多的内存使用,但如果您需要在插入之前修改一些记录时可能有用):

public void populateDB(){

    ContentValues[] initialValues = new ContentValues[animalName.length];

    for(int i = 0; i < animalName.length; i++){
        // create a new ContentValues for each object
        initialValues[i] = new ContentValues();
        initialValues[i].put(KEY_ANIMALNAME, animalName[i]);
    }

    // now our contentvalues is filled we can insert them all
    for(int i = 0; i < animalName.length; i++){
        DB.insert(ANIMAL_TABLE, null, initialValues[i]);
    }
}

【讨论】:

  • 感谢 Joseph 的回复,= 是我分配游标并返回它时留下的,而不是上面的方法,删除后没有任何变化。
  • 在这种情况下,根据@Rajath 的评论-myCursor.getCount() 给你什么?如果答案是 1,那么数据库只会从数据库中返回 1 条记录。
  • getCount() 返回 1。我用我的方法编辑了原始帖子来填充数据库,我似乎无法选择它的问题。所以我的问题基本上是光标返回应该有几行时只有 1 行。
  • 是的,问题在于填充数据库 - 您所做的只是插入一条记录,您只是在多次更改 ContentValues 的 KEY_ANIMALNAME 值!请参阅我编辑的解决方案答案,或者您可以创建一个 ContentValues[] 数组并使用 bulkInsert。出于性能原因,最好在您插入大量记录的事务中进行插入。
  • 谢谢。当然,我以后不会忘记这一步,你为我节省了很多头发,最重要的是时间!你能解释一下为什么 rowIds 有所作为吗?我的理解是插入返回“新插入行的行ID,如果发生错误则返回-1”。如果此操作在插入后完成,插入时有何不同?
【解决方案2】:

你试过了吗

myCursor.moveToFirst()

【讨论】:

  • 嗨 Rajath 感谢您的建议,我在从数据库中检索光标后立即添加了此代码,它没有产生任何影响。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-08
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多