热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SQLite更改数据库中项目的排序顺序-SQLiteChangeSortOrderforitemsondatabase

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

So imagine this is a quick mockup of my database:

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

enter image description here

The items from the database are presented to the user per list, each list being displayed on a new fragment, which are displayed on a viewpager. So let's say in this hypotetical case, there would be two fragments on the viewpager, first fragment would display first_list and second fragment would display second_list. Here's the code for that query:

来自数据库的项目按列表呈现给用户,每个列表显示在新片段上,该片段显示在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);
}

Where SORT_ORDER is order_in_list, this works well, to begin with.

在SORT_ORDER是order_in_list的地方,这很有效,首先。

Now, the listviews are re-arrangeable using a public library, which attempts to allow the user to control the order of the items in each list. Here's where I am having issues, there is no add(int index, Object object) for the cursor, or some other easy way to manage the sorting. I first thought I could simply call mDatabase.update() to change the value for order_in_list but that works, but the results are not as intended. For example, user drags item two to position zero, remeber: zero-index values, we would now have two items with order_in_list as zero. And although I can call mDatabase.update() on item one to update his position to one, imagine how much work that'd be to handle several items on a well-formed database.

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

Does anyone have any good suggestions on how I could work this out? I thought I had been clever by adding the extra col for sorting purposes :(

有没有人对如何解决这个问题有任何好的建议?我认为通过添加额外的col用于分类目的我很聪明:(

INB4:

INB4:

Yes, I Know arrays handle this well. But the database doesn't only store 4 cols, it has many more fields. Populating arrays each time from the database would be a waste of time and effort. And I would, anyways, have to write back to the database when the app is closed.

是的,我知道数组处理得很好。但是数据库不仅存储4个cols,还有更多的字段。每次从数据库填充数组都是浪费时间和精力。无论如何,当应用程序关闭时,我会写回数据库。

EDIT So I changed the listview to only display one String of text, and further columns upon actual clicking on the item (and therefore displaying a new fragment with the specified list item data). This allowed me to simply keep an ArrayAdapter which easily handles the drag and drop. During onStop, I update the reference only if there was a change that required to be saved:

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

@Override
public void onStop() {
    if (updateDbOnExit) {
        //Update rows on database.
        for (int i = 0; i 

Where MoveListItemTo updates the value for order_in_list:

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

That will work for now. However, I am still interested on knowing if there is an alternate way, especially when for example, the adapter is using data from more than one column on the database, and is therefore required to use a CusorAdapter and not a regular ArrayAdapter, which in turn requires the Database itself to update upon each Drag and Drop to reflect the change on the UI via cursorAdapter.swapCursor(). As stated, updating ALL of the items on a database upon each drag (which realistically doesn´t happen that often btw), is expensive, updating only Two rows, would be a saner choice.

那将是有效的。但是,我仍然有兴趣知道是否有另一种方法,特别是当例如适配器使用数据库中多个列的数据时,因此需要使用CusorAdapter而不是常规的ArrayAdapter, turn需要数据库本身在每次拖放时更新,以通过cursorAdapter.swapCursor()反映UI上的更改。如上所述,在每次拖动时更新数据库上的所有项目(实际上不会经常发生这种情况),这样做很昂贵,只更新两行,这将是一个更健全的选择。

2 个解决方案

#1


1  

I would suggest that you have an additional column, user_specified_order which would represent the user's reordering of the rows in the UI via drag-drop.

我建议你有一个额外的列user_specified_order,它代表用户通过拖放重新排序UI中的行。

You must update each row when its user_specified_order value is invalidated by the drag-drop repositioning. When to persist that value is up to you -- either at the "end" of the user's manipulations, however that be defined (e.g. click on Save button) or after each drag/drop if there is no clearcut UI indicator of "end of manipulation".

通过拖放重新定位使user_specified_order值无效时,必须更新每一行。何时保持该值取决于您 - 要么在用户操作的“结束”,要么定义(例如,单击“保存”按钮),或者在每次拖放后如果没有明确的UI指示符“结束”操纵”。

EDIT: ContenProvider in Android: Android - Can you update a Cursor for SQLite results?

编辑:Android中的ContenProvider:Android - 您可以更新SQLite结果的Cursor吗?

Android SQLite transactions: Android Database Transaction

Android SQLite事务:Android数据库事务

#2


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

我只是想要一种更有效的方法来更新数据库中的字段,而不是手动更新每一行

Make the user-specified-order column a decimal, not an integer. Then you need to update only the moved row(s).

使用户指定的顺序列为小数,而不是整数。然后,您只需要更新已移动的行。

Allow negative numbers.

允许负数。

0.00 cat
1.00 aardvark
2.00 wolf
3.00 dog

If "dog" is dragged above "wolf" then "dog" becomes 1.50 and no need to change other rows. If "aardvark" is dragged above "cat" (special case -- prepending to list rather than inserting between rows) then subtract 1 from the topmost value, and "aardvark" becomes -1.00.

如果“狗”被拖到“狼”之上,那么“狗”变为1.50并且不需要改变其他行。如果“aardvark”被拖到“cat”之上(特殊情况 - 前置于列表而不是插入行之间),则从最顶层的值中减去1,“aardvark”变为-1.00。

This will require you to know the values of the adjacent rows, but you won't have to update them. Only the moved row's value must change.

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


推荐阅读
author-avatar
失心人2702939300
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有