2

所以想象一下这是我的数据库的一个快速模型:

在此处输入图像描述

数据库中的项目按列表呈现给用户,每个列表都显示在一个新片段上,这些片段显示在一个视图页面上。因此,假设在这种假设情况下,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_ORDERorder_in_list这很好用。

现在,列表视图可以使用公共重新排列,它试图允许用户控制每个列表中项目的顺序。这是我遇到问题的地方,没有add(int index, Object object)光标,或者其他一些简单的方法来管理排序。我首先认为我可以简单地调用mDatabase.update()来更改值,order_in_list但这可行,但结果并不如预期。例如,用户将项目二拖到位置,请记住:零索引值,我们现在将有两个项目order_in_list为零。虽然我可以调用第一项mDatabase.update()来将他的位置更新为一项,想象一下在一个格式良好的数据库中处理多个项目需要做多少工作。

有人对我如何解决这个问题有什么好的建议吗?我以为我很聪明地添加了额外的 col 进行排序:(

INB4:

是的,我知道数组可以很好地处理这个问题。但该数据库不仅存储 4 个列,它还有更多字段。每次从数据库中填充数组都是浪费时间和精力。无论如何,我必须在应用程序关闭时写回数据库。

编辑所以我将列表视图更改为仅显示一个文本字符串,并在实际单击该项目时显示更多列(因此显示具有指定列表项数据的新片段)。这让我可以简单地保留一个 ArrayAdapter 来轻松处理拖放操作。在 onStop 期间,我仅在需要保存更改时才更新参考:

@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();
}   

其中 MoveListItemTo 更新 order_in_list 的值:

 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();
}

现在可以了。但是,我仍然想知道是否有其他方法,尤其是当适配器使用数据库中多个中的数据时,因此需要使用 CusorAdapter 而不是常规的 ArrayAdapter,这在turn 要求数据库本身在每次拖放时更新,以通过cursorAdapter.swapCursor(). 如前所述,在每次拖动时更新数据库上的所有项目(实际上并不经常发生这种情况),代价高昂,只更新行,将是一个更明智的选择。

4

2 回答 2

6

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

如果将“dog”拖到“wolf”上方,则“dog”变为 1.50,无需更改其他行。如果将“aardvark”拖到“cat”上方(特殊情况——在列表之前而不是在行之间插入),则从最高值中减去 1,“aardvark”变为 -1.00。

这将要求您知道相邻行的值,但您不必更新它们。只有移动的行的值必须改变。

于 2013-03-10T15:57:29.307 回答
1

我建议您有一个额外的列 user_specified_order 表示用户通过拖放对 UI 中的行进行重新排序。

当其 user_specified_order 值因拖放重新定位而失效时,您必须更新每一行。何时保留该值取决于您——无论是在用户操作的“结束”时,但要定义(例如单击保存按钮)或在每次拖放后,如果没有明确的 UI 指示“结束操纵”。

编辑:Android 中的 ContenProvider: Android - 你可以更新 SQLite 结果的光标吗?

Android SQLite 事务: Android 数据库事务

于 2013-03-10T13:20:21.863 回答