2

したがって、これが私のデータベースの簡単なモックアップであると想像してください。

ここに画像の説明を入力してください

データベースのアイテムはリストごとにユーザーに表示され、各リストは新しいフラグメントに表示され、ビューページャーに表示されます。したがって、この架空のケースでは、ビューページャーに2つのフラグメントがあり、最初のフラグメントはfirst_listを表示し、2番目のフラグメントは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、そもそもこれはうまく機能します。

現在、リストビューは、ユーザーが各リスト内のアイテムの順序を制御できるようにするパブリックライブラリを使用して再配置できます。ここで私は問題を抱えadd(int index, Object object)ています。カーソルや、並べ替えを管理する他の簡単な方法はありません。mDatabase.update()の値を変更するために単純に呼び出すことができると最初に思いましorder_in_listたが、それは機能しますが、結果は意図したとおりではありません。たとえば、ユーザーがアイテム2を位置ゼロにドラッグします。覚えておいてください:ゼロインデックス値。これで、ゼロとして2つのアイテムが作成order_in_listされます。そして、私はアイテム1を呼び出しmDatabase.update()て、彼の位置を1に更新することができますが、整形式のデータベースでいくつかのアイテムを処理するのにどれだけの作業が必要か想像してみてください。

誰かが私がこれを解決する方法について何か良い提案がありますか?並べ替えの目的で余分な列を追加することで、私は賢かったと思いました:(

INB4:

はい、私は配列がこれをうまく処理することを知っています。ただし、データベースには4つの列が格納されるだけでなく、さらに多くのフィールドがあります。データベースから毎回アレイにデータを入力することは、時間と労力の無駄になります。とにかく、アプリを閉じたときにデータベースに書き戻す必要があります。

編集そこで、リストビューを変更して、テキストの1つの文字列と、アイテムを実際にクリックしたときにさらに列を表示するようにしました(したがって、指定されたリストアイテムデータを含む新しいフラグメントを表示します)。これにより、ドラッグアンドドロップを簡単に処理できる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();
}

それは今のところうまくいくでしょう。ただし、別の方法があるかどうか、特にアダプターがデータベースの複数の列のデータを使用しているため、通常のArrayAdapterではなくCusorAdapterを使用する必要がある場合は特に興味があります。 turnは、を介してUIに変更を反映するために、ドラッグアンドドロップごとにデータベースcursorAdapter.swapCursor()自体を更新する必要があります。前述のように、ドラッグするたびにデータベース上のすべてのアイテムを更新することは(現実的にはそれほど頻繁には発生しません)、コストがかかり、2行のみを更新するのが賢明な選択です。

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

user-specified-order 列を整数ではなく 10 進数にします。次に、移動した行のみを更新する必要があります。

負の数を許可します。

0.00 cat
1.00 aardvark
2.00 wolf
3.00 dog

「犬」を「オオカミ」の上にドラッグすると、「犬」は 1.50 になり、他の行を変更する必要はありません。「aardvark」が「cat」の上にドラッグされた場合 (特殊なケース -- 行間に挿入するのではなくリストの前に追加)、一番上の値から 1 を引くと、「aardvark」は -1.00 になります。

これには、隣接する行の値を知る必要がありますが、それらを更新する必要はありません。移動した行の値のみを変更する必要があります。

于 2013-03-10T15:57:29.307 に答える
1

ドラッグ アンド ドロップによる UI でのユーザーの行の並べ替えを表す追加の列 user_specified_order を用意することをお勧めします。

ドラッグ アンド ドロップの再配置によって user_specified_order 値が無効になった場合は、各行を更新する必要があります。その値をいつ保持するかはあなた次第です。ユーザーの操作の「最後」に定義されますが (たとえば、[保存] ボタンをクリックします)、または「最後」の明確な UI インジケーターがない場合は、各ドラッグ/ドロップの後です。操作」。

編集: Android の ContenProvider: Android - SQLite の結果のカーソルを更新できますか?

Android SQLite トランザクション: Android データベース トランザクション

于 2013-03-10T13:20:21.863 に答える