我有一个ListView
动态添加的项目。添加项目时,会将其添加到ListView
SQLite 数据库并插入到 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
then cat
then horse
。ListView 以正确的顺序显示它们(horse
在顶部)。如果我然后删除一个项目,可以说:cat
, ListView 更新并且一切都很好。但是,如果我然后重新启动应用程序,initList()
则会调用。这就是问题发生的地方 -不是 cat
从列表中删除,而是horse
或dog
。
我认为问题可能出在以下几点:
a) 在 initList() - 它没有添加正确的项目
b) 在 removeItem() - 它没有从数据库中删除正确的项目。
c) 在 getList() 中 - 可能是带有光标的东西???
这认为 b) 更有可能,但我不知道问题到底出在哪里,也不知道要改变什么。
编辑:
经过一些测试,我发现我是对的,b)是它出错的地方。
重现步骤:
创建三个项目:cat
then dog
then horse
。以正确的ListView
顺序显示它们,即horse
在顶部,cat
在底部。显示Database
它们cat
的顶部horse
和底部。
当我正确删除horse
(顶部ListView
,底部Database
)ListView
更新时,但在数据库中它不是horse
已被删除,而是实际上cat
。
所以由于删除错误,当Database
使用 恢复时ListView
,ListView 出现错误。
我希望这能让事情更清楚!
编辑2:这就是我创建表的方式:
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 );";
这是 getContentValues():
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;
}
编辑 3:
我基本上把它缩小到这样一个事实,因为 ListView 和数据库中的项目顺序不同,所以按它们在列表中的位置删除项目是行不通的。那么一个可能的解决方案是反转数据库中项目的顺序以匹配 ListView (好主意/可能?)。
编辑 3.1:
https://stackoverflow.com/a/7348117/2442638
这种降序可能会有所帮助。我不知道我应该把它放在哪里
编辑 3.5:
我现在可以订购了。删除几乎可以工作,但现在有一个问题是第一次删除不起作用。之后的其余工作。我按_id
and 排序,因为它autoincrement
可能从 1 或 0 开始,而列表从另一个开始。我会做更多的研究