删除,恢复ListView和数据库中的项目

时间:2013-08-10 09:29:38

标签: android android-listview sqlite

我有一个ListView项,其中包含动态添加的项目。添加项目时,会将其添加到ListView并插入到SQLite数据库中,以便保存列表中的项目。我还可以通过获取项目的位置来删除特定项目,然后使用该信息删除它。

这就是我添加项目(我使用多个类)的方式:

DataModel.class

public void addItem(Object data) {

        String string = String.valueOf(data);

        mPlanetsList.add(createPlanet("planet", string)); 
        History history = new History();
        history.getDataHashMap().put("planet", data);
        history.addToHistoryDB();

        mHistoryList.add(history);

        if (null != mOnItemAddHandler) {
            mOnItemAddHandler.onItemAdded(data);
        }
    }

History。class:

public void addToHistoryDB() {

        MySQLiteOpenHelper mDbHelper = MySQLiteOpenHelper.getInstance();
        SQLiteDatabase db = mDbHelper.getWritableDatabase();

        ContentValues values = getContentValues();

        rawId = (int) db.insert(TABLE_NAME, COL_ID, values);
        db.close();
    }

这就是我删除项目的方式:

DataModel。class:

public void removeItem(int index) { 

        if (mPlanetsList == null || index < 0 || index >= mPlanetsList.size()) {
            return;
        }
        // remove from mPlanetList
        mPlanetsList.remove(index);

        History history = mHistoryList.get(index);
        mHistoryList.remove(index);
        if (null != history) {
            history.remove();
            history = null;
        }

        // notify, the HistoryFragment will update view
        if (null != mOnItemAddHandler) {
            mOnItemAddHandler.onItemRemove(index);
        }

History。class:

public void remove() {
        MySQLiteOpenHelper mDbHelper = MySQLiteOpenHelper.getInstance();
        SQLiteDatabase db = mDbHelper.getWritableDatabase();

        int r = db.delete(TABLE_NAME, "_id = ?",  // delete the int r ??
                new String[] { String.valueOf(rawId) }); 
        db.close();
    }

当应用程序从“最近的应用程序”中删除或重新启动时,将调用initList(),从数据库中恢复ListView项目。

这是代码:

DataModel

private void initList() {



        mHistoryList = History.getList();
        for (int i = 0; i < mHistoryList.size(); i++) {
            Object obj = mHistoryList.get(i).getDataHashMap().get("planet");
            mPlanetsList.add(createPlanet("planet", String.valueOf(obj))); 
        }
    }

History

public static ArrayList<History> getList() {
        Cursor cursor = null;
        try {
            MySQLiteOpenHelper mDbHelper = MySQLiteOpenHelper.getInstance();
            SQLiteDatabase db = mDbHelper.getWritableDatabase();
            String sql = "select * from " + History.TABLE_NAME;
            ArrayList<History> list = new ArrayList<History>();
            cursor = db.rawQuery(sql, null);
            if (cursor != null) {
                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor
                        .moveToNext()) {
                    History item = new History();
                    item.fromCuror(cursor);
                    list.add(item);
                }
            }
            return list;
        } finally {
            if (null != cursor && Integer.parseInt(Build.VERSION.SDK) < 14) {
                cursor.close();
            }
        }
    }

只要列表顺序没有改变,这种方法就可以正常工作 - 我可以添加项目并删除项目,这一切都很有效。但是,我希望将项目添加到列表顶部而不是底部。

所以我读到如何将项目添加到ListView的顶部,并发现通过在添加项目时添加0作为位置,新项目将转到列表的顶部。

mPlanetsList.add(0, createPlanet("planet", string)); // I put the 0 in wherever the item is added eg when adding from the database

但是,当我这样做时,ListView中查看/删除的项目不会继续与数据库中的数据相对应。例如,让我们说我向列表中添加了三个项目:dog然后cat然后horse。 ListView以正确的顺序显示它们(顶部为horse)。如果我然后删除一个项目,让我们说:cat,ListView更新,每一个都很好。但是,如果我重新启动应用程序,则会调用initList()。这就是问题发生的地方 - 从列表中删除 cat,它是horsedog

我认为问题可能存在的可能点:

a)在initList()中 - 它没有添加正确的项

b)在removeItem()中 - 它没有从数据库中删除正确的项目。

c)在getList()中 - 可能是光标???

这种想法b)更有可能,但我不知道问题的确切位置或改变方法。

修改

经过一些测试后,我发现我说得对,b)是出错的地方。

重现的步骤:

创建三个项目:cat然后dog然后horseListView以正确的顺序显示它们,即顶部为horse,底部为catDatabase在顶部显示cat,在底部显示horse

当我删除horseListView的顶部,Database的底部)ListView正确更新时,但在数据库中,horse不是cat已删除但实际上已Database

因为删除错误,当ListView用于恢复public static final String TABLE_NAME = "history_table"; public static final String COL_TITLE = "title"; public static final String COL_CONTENT = "content"; public static final String COL_DATE = "date"; public static final String COL_TYPE = "type"; public static final String COL_ONGOING = "ongoing"; public static final String COL_DATA = "data"; public static final String COL_ID = "_id"; public static final String DATABASE_CREATE = "create table " + TABLE_NAME + "(" + COL_ID + " integer primary key autoincrement, " + COL_TITLE + " text not null, " + COL_CONTENT + " text not null, " + COL_DATE + " text not null, " + COL_TYPE + " text not null, " + COL_ONGOING + " text not null, " + COL_DATA + " text not null );"; 时,ListView显示错误。

我希望这会让事情更清楚!

编辑2:这是我创建表格的方式:

public ContentValues getContentValues() {

        ContentValues values = new ContentValues();
        values.put(History.COL_TITLE, "MyTitle");
        values.put(History.COL_CONTENT, "MyContent");
        values.put(History.COL_DATE, "Date placeholder");
        values.put(History.COL_TYPE, "QuickNote");
        values.put(History.COL_ONGOING, "Ongoing placeholder");
        values.put(History.COL_DATA, new JSONObject(mDataHashMap).toString());

        return values;
    }

这是getContentValues():

_id

编辑3:

我基本上已将其缩小到这样的事实:因为ListView和数据库中的项目顺序不同,所以通过列表中的邮件删除项目不起作用。那么一个可能的解决方案是反转数据库中的项目顺序以匹配ListView(好主意/可能吗?)。

编辑3.1:

https://stackoverflow.com/a/7348117/2442638

这个降序的顺序可能有所帮助。我不知道应该把它放在哪里

编辑3.5:

我现在有订单工作。删除几乎可以工作,但现在有一个问题,第一次删除不起作用。其余的工作在那之后。我按autoincrement排序,因为它是{{1}},它可能从1或0开始,列表从另一个开始。我会做更多的研究

1 个答案:

答案 0 :(得分:0)

应用中有两个列表:mHistoryListmPlanetsList,您应该保持其中的数据顺序相同。

您可以通过调用DataModel中的方法listview将项目添加到addItem的顶部:

public void addItem(Object data) {

    History history = new History();
    history.getDataHashMap().put("planet", data);
    history.addToHistoryDB();

    mHistoryList.add(0, history);
    mPlanetsList.add(0, history.createPlanet());

    if (null != mOnItemAddHandler) {
        mOnItemAddHandler.onItemAdded(data);
    }
}

然后新数据将位于listview

的顶部

应用程序重启后,将调用以下代码:

private void initList() {

    mHistoryList = History.getList();
    for (int i = 0; i < mHistoryList.size(); i++) {
        mPlanetsList.add(mHistoryList.get(i).createPlanet());
    }
}

我们应该确保来自History.getList();的数据具有相同的顺序,换句话说,列表头部的新数据时间。

所以我们应该将代码更改为(order by _id desc):

public static ArrayList<History> getList() {
    Cursor cursor = null;
    try {
        MySQLiteOpenHelper mDbHelper = MySQLiteOpenHelper.getInstance();
        SQLiteDatabase db = mDbHelper.getWritableDatabase();

        // order by _id desc
        String sql = "select * from " + History.TABLE_NAME + " order by _id desc";
        ArrayList<History> list = new ArrayList<History>();
        cursor = db.rawQuery(sql, null);
        if (cursor != null) {
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                History item = new History();
                item.fromCuror(cursor);
                list.add(item);
            }
        }
        return list;
    } finally {
        if (null != cursor && Integer.parseInt(Build.VERSION.SDK) < 14) {
            cursor.close();
        }
    }
}