java 如何通过更改数据库中的值来更改recyclerView项的顺序?

u59ebvdq  于 2023-02-02  发布在  Java
关注(0)|答案(1)|浏览(170)

在我的应用程序中,用户应该能够更改项目的顺序。我通过SELECT语句按Order字段排序表中的数据,并将结果存储在List中。然后,我在Recycler View中显示List数据。
我想将“Item 5“从回收器视图位置4和Order字段值12移动到回收器视图位置1。

我的第一个问题:如何使用Java/Kotlin将项目5移动到回收器位置1?
我的第二个问题:如何将项目5移动到回收站位置1并相应地更改数据库中的订单字段?意味着当我将项目5移动到回收站位置1时,项目5订单字段应更改为5,项目2订单字段应更改为7,项目3订单字段应更改为9,项目4订单字段应更改为12
**The Recycler查看商品:**x1c 0d1x

kpbwa7wx

kpbwa7wx1#

回答一,在更改数据库后使用新数据重建/刷新recyclerview。
答案二粗略地说你必须

1.确定受影响行的范围(顺序介于从到之间的行)
1.使用移动方向上下一行的值移动受影响行(不是要移动的行)的值
1.更改移动行中的值
这是相当复杂的,特别是当所有的阶段都要合并的时候。然而,这可以通过使用公共表表达式(只在查询期间存在的临时表)的SQLite来实现。
以下是解决所提出问题的演示,即从:-

这是一个演示(注解和格式化),演示了将在Room中实现的核心查询(注解表示核心查询):-

/* Just in case the environment has not been cleanup, clean it up*/
DROP TABLE If EXISTS example;
/* Create the table to be demonstrated */
CREATE TABLE IF NOT EXISTS example (
    orderinrecyclerview INTEGER, 
    orderfieldvaluesfromtable INTEGER, 
    textfieldvaluesfromtable TEXT
);
/* Add the data for the demo */
INSERT INTO example VALUES
    (0,2,'Item 1'),
    (1,5,'Item 2'),
    (2,7,'Item 3'),
    (3,9,'Item 4'),
    (4,12,'Item 5'),
    (5,16,'Item 6')
;
/* Show the original data as RESULT 1 */
SELECT * FROM example ORDER BY orderfieldvaluesfromtable;

/*<<<<<<<<<< THIS IS THE CORE QUERY BEING DEMONSTRATED >>>>>>>>>>*/
WITH 
    /* CTE (Common Table Expression which is temp table that exists only for the duration of the query) 
        store the from and to values for the move to be made, 
        so values can be obtained whenever needed
    */
    cte_args(fromvalue,tovalue) AS (
        SELECT 
            12 /* will not be hard coded but passed/bound via  arg*/,
            5 /* will not be hard coded but passed/bound via arg */
        ) /* from to values*/,
        
    /* Second CTE to get all the rows that will be affected, along with the new replacement value */
    /* This is done in two stages 
        stage one gets all affected rows EXCEPT the actual row being moved.
        stage two gets the actual row being changed
    */
    cte_rowstochange(rowid,originalorder,neworder) AS (
        SELECT 
            rowid, /* the rowid (always exists for tables unless WITHOUT ROWID table (ROOM does not support WITHOUT ROWID tables)) */
            orderfieldvaluesfromtable,
            (
                SELECT orderfieldvaluesfromtable 
                    FROM example 
                    WHERE orderfieldvaluesfromtable > e.orderfieldvaluesfromtable /* e is the primary query example table as opposed to subquery example table */
                    ORDER BY orderfieldvaluesfromtable ASC /* want the next higher */
                    LIMIT 1 /* only want the 1 value */
            ) /* The value of the order in the next row (next higher order) */
            FROM example AS e /* need to alias the table for WHERE clause above which accesses the same table */
            WHERE orderfieldvaluesfromtable >= (SELECT tovalue FROM cte_args)
            AND orderfieldvaluesfromtable < (SELECT fromvalue FROM cte_args)
            UNION ALL SELECT 
                rowid,
                orderfieldvaluesfromtable,
                (
                    SELECT tovalue FROM cte_args
                )
                FROM example
                WHERE orderfieldvaluesfromtable = (SELECT fromvalue FROM cte_args)
                ORDER BY orderfieldvaluesfromtable ASC
    )
UPDATE example 
    SET orderfieldvaluesfromtable = (
        SELECT neworder 
        FROM cte_rowstochange 
        WHERE example.rowid = cte_rowstochange.rowid
    ) 
    WHERE rowid IN (
        SELECT rowid FROM cte_rowstochange
        )
;
/*<<<<<<<<<< END OF THE CORE QUERY >>>>>>>>>>*/
SELECT * FROM example ORDER BY orderfieldvaluesfromtable;

/* Cleanup testing environment */
DROP TABLE If EXISTS example;

要在Room中使用上述内容,您只需要核心查询(调整为from和to值的表参数),例如:-

Query("WITH cte_args(:fromvalue,:tovalue) AS (SELECT    12,5),cte_rowstochange(rowid,originalorder,neworder) AS (SELECT rowid,orderfieldvaluesfromtable,(SELECT orderfieldvaluesfromtable FROM example WHERE orderfieldvaluesfromtable > e.orderfieldvaluesfromtable ORDER BY orderfieldvaluesfromtable ASC LIMIT 1) FROM example AS e WHERE orderfieldvaluesfromtable >= (SELECT tovalue FROM cte_args) AND orderfieldvaluesfromtable < (SELECT fromvalue FROM cte_args) UNION ALL SELECT rowid,orderfieldvaluesfromtable,(SELECT tovalue FROM cte_args) FROM example WHERE orderfieldvaluesfromtable = (SELECT fromvalue FROM cte_args) ORDER BY orderfieldvaluesfromtable ASC) UPDATE example SET orderfieldvaluesfromtable = (SELECT neworder FROM cte_rowstochange WHERE example.rowid = cte_rowstochange.rowid) WHERE rowid IN (SELECT rowid FROM cte_rowstochange);")
fun moveOrderDown(fromvalue: Int,tovalue: Int)

*显然,组件名称(其中的表和列)必须更改以适应实际的表和列,即

  • 必须更改表名example以反映该表的内容
  • 必须更改表中的列顺序字段值。
  • 其他组件名称可以保持原样,即
    *行IDe目标值起始值新单词cte_argscte_行目标更改
  • rowid之外的所有列都可以根据需要一致地更改。rowid必须为rowid它是隐藏列的名称,该列存在于所有非WITHOUT ROWID表或虚拟表(Room不直接支持其中任何一个(全文搜索又名FTS是一个例外)的表中。
    重要提示以上只是解决了将订单移动到较低订单的问题。移动到较高订单的逻辑与此类似,但相反。您可能需要moveOrderUp函数。您可能需要第三个函数来确定调用哪个移动函数,例如
fun moveOrder(fromvalue: Int, tovalue: Int) {
    if (fromvalue == tovalue) return
    if (fromvalue > tovalue) {
        moveOrderDown(fromvalue,tovalue)
    } else {
        moveOrderUp(fromvalue,tovalue)
    }
}

此外,该解决方案是原则性的,尚未经过彻底测试,因此可能存在未检测到的问题。

相关问题