想象一下,这是我的数据库的快速模型:
数据库中的项目按列表呈现给用户,每个列表显示在新的片段上,这些片段显示在viewpager上。因此,在这个hypotetical案例中,在viewpager上会有两个片段,第一个片段会显示 first_list ,第二个片段会显示 second_list 。这是该查询的代码:
public static Cursor getListItems (final Context context, String listName) {
if (mDatabase == null || !mDatabase.isOpen())
open(context); //This gets the writable db.
String where = LIST_NAME + " = '" + listName + "'";
return mDatabase.query(TABLE_LIST_ITEMS, PROJECTION_LIST_ITEMS,
where, null, null, null, SORT_ORDER);
}
SORT_ORDER
order_in_list
的位置,开始时效果很好。
现在,列表视图可以使用公共library重新排列,它试图允许用户控制每个列表中项目的顺序。这是我遇到问题的地方,光标没有add(int index, Object object)
,或者其他一些简单的方法来管理排序。我首先想到我可以简单地调用mDatabase.update()
来更改order_in_list
的值,但这样可行,但结果并非如预期。例如,用户拖动第二项以定位零,记住:零指数值,我们现在拥有两个项{{1}为零。虽然我可以在第一项上致电order_in_list
以将其职位更新为一个,但想象一下,在一个以上的项目上处理多个项目需要做多少工作形成数据库。
有没有人对如何解决这个问题有任何好的建议?我认为通过添加额外的col用于分类目的我很聪明:(
INB4:
是的,我知道数组处理得好。但是数据库不仅存储4个cols,还有更多的字段。每次从数据库填充数组都是浪费时间和精力。无论如何,当应用程序关闭时,我会写回数据库。
编辑所以我将listview更改为仅显示一个文本字符串,并在实际单击该项目时显示更多列(因此显示具有指定列表项数据的新片段)。这使我可以简单地保留一个可以轻松处理拖放的ArrayAdapter。在onStop期间,只有在需要保存的更改时才更新引用:
mDatabase.update()
其中MoveListItemTo更新order_in_list的值:
@Override
public void onStop() {
if (updateDbOnExit) {
//Update rows on database.
for (int i = 0; i < items.size(); i++) {
//Set the order in list be the actual order on the array.
Constants.LogMessage("Updating db content");
DbManager.moveListItemTo(getActivity(), items.get(i), i);
}
updateDbOnExit = false;
}
super.onStop();
}
这将暂时有用。但是,我仍然有兴趣知道是否有其他方法,特别是当例如适配器使用数据库中超过一个列的数据时,因此需要使用CusorAdapter和不是常规的ArrayAdapter,而是需要数据库本身在每次拖放时更新,以通过 public static void moveTaskItemTo (final Context context, String item, int to) {
if (mDatabase == null || !mDatabase.isOpen())
open(context);
String where = COL_CONTENT + " = '" + item+ "'";
ContentValues mContentValues = new ContentValues();
mContentValues.put(ORDER_IN_LIST, to);
int rows = mDatabase.update(TABLE_LIST_ITEMS, mContentValues, where, null);
Constants.LogMessage(rows + " row updated. Item moved to position: " + to);
close();
}
反映UI上的更改。如上所述,每次拖动时更新数据库中所有的项目(实际上通常不会发生这种情况),这是非常昂贵的,只更新两个行,一个更健全的选择。
答案 0 :(得分:4)
I just meant I wanted a more effective way to update the fields in the db, rather than manually updating each and every single row
使用户指定的顺序列为小数,而不是整数。然后,您只需要更新已移动的行。
允许负数。
0.00 cat
1.00 aardvark
2.00 wolf
3.00 dog
如果“狗”被拖到“狼”之上,那么“狗”变为1.50并且不需要改变其他行。如果将“aardvark”拖到“cat”之上(特殊情况 - 前置到列表而不是在行之间插入),则从最顶层的值中减去1,“aardvark”变为-1.00。
这将要求您知道相邻行的值,但您不必更新它们。只有移动的行的值必须更改。
答案 1 :(得分:1)
我建议您有一个额外的列user_specified_order,它代表用户通过拖放操作重新排序UI中的行。
如果通过拖放重新定位使user_specified_order值无效,则必须更新每一行。何时持久该值取决于您 - 无论是在用户操作的“结束”,还是定义(例如,单击“保存”按钮),或者在每次拖放后如果没有clearcut操纵结束的UI指示。
编辑:Android中的ContenProvider: Android - Can you update a Cursor for SQLite results?
Android SQLite交易: Android Database Transaction