更改listView

时间:2017-10-26 08:33:48

标签: android sqlite date listview

我的应用程序中有一个按钮重新安排,按下它会自动更改待办事项的过去日期与当前日期,但问题是,使用以下代码,它还会更改当前日期的当前日期一,我没有任何其他代码 - 如果但它仍然用当前更改未来日期。

public void updateDates2() {
    SQLiteDatabase db = mHelper.getWritableDatabase();
    Cursor cursor = null;
    Calendar c = Calendar.getInstance();
    List<String> array = new ArrayList<String>();
    SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
    cursor = db.query(TaskContract.TaskEntry.TABLE_NAME,
            new String[]{TaskContract.TaskEntry._ID,
                    TaskContract.TaskEntry.COLUMN_DATE,
            },
            null, null, null, null, null);

    String formattedDate = formatter.format(c.getTime());

    while (cursor.moveToNext()) {
        //Getting dates into the array using Cursor.
        String datesfromdb = cursor.getString(cursor.getColumnIndex("date"));
        array.add(datesfromdb);
    }
    ContentValues cv = new ContentValues();
    String TEMPPCOLNAME = "checkdate";
    Cursor csr = db.query(TaskContract.TaskEntry.TABLE_NAME, new String[]{
                    // All existing columns
                    "*",
                    "rowid as uid",
                    // generate reformatted date column named checkdate usable by date functions
                    // i.e. converts dd/mm/yyyy to yyyy-mm-yy
                    "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",7,4)||'-'||" +
                            "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",4,2)||'-'||" +
                            "substr( " + TaskContract.TaskEntry.COLUMN_DATE + ",1,2) AS " + TEMPPCOLNAME},
            // where clause to only include properly formatted dates and those who date is less
            // than or equaly to today's date
            TEMPPCOLNAME + "<= date('now') AND " +
                    "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",3,1) = '/' AND " +
                    "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",6,1) = '/'",
            null, null, null, null
    );


    Toast.makeText(this, csr.toString() , Toast.LENGTH_SHORT).show();
    while (csr.moveToNext()) {
        for (int i = 0; i < array.size(); i++) {
            if (array.get(i).equals(formattedDate)) {
                //If comparision matches, then incrementing the current date by one.
                c.add(Calendar.DATE, 1);
                formattedDate = formatter.format(c.getTime());
            } else {
                //if the date doesn't matches then returning the date to the db.update to set this date to the current task.
                cv.put(TaskContract.TaskEntry.COLUMN_DATE, formattedDate);
            }
        }

        if (

                db.update(TaskContract.TaskEntry.TABLE_NAME, cv, "rowid=?", new String[]{
                        String.valueOf(csr.getLong(csr.getColumnIndex("uid")))}
                ) > 0) {
            Log.d("UPDT2", "Row Updated OK.");
        } else {
            Log.d("UPDT2", "Update failed.");
        }

    }

1 个答案:

答案 0 :(得分:0)

我相信你的问题正如你所描述的那样: -

db.update(TaskContract.TaskEntry.TABLE_NAME, cv, String.valueOf(idx1), null);

,特别是第3个(WHERE子句)参数,即String.valueOf(idx1)

你实际上在说WHERE n( n是列TaskContract.TaskEntry.COLUMN_DATE 的偏移/索引)。如果此列索引大于0,则表达式将有效,因此每行都将更新。

因此,此更新只需执行一次,如果列索引大于0(true),则会更新所有行。这似乎是您所描述的行为。

您需要参数类似TaskContract.TaskEntry.COLUMN_DATE = 'CurrentDate'

或者最好TaskContract.TaskEntry.COLUMN_DATE=?使用第4个参数解析占位符,例如newString[]{dateDB}

这会更新该日期的所有行,这可能会导致针更新尝试。例如,如果您有两个相同的过去日期,则当光标到达该行并且光标到达另一行时,两个日期都会更新。

我建议只提取要更新的行,这并不容易,因为您似乎将日期存储为dd / mm / yyyy(根据日期顺序不容易排序)。但是,您可以通过在提取的游标中创建一个列来重新格式化日期并允许对其进行检查。

这看起来有点复杂,这是一个例子: -

String TEMPPCOLNAME = "checkdate";
        Cursor csr = db.query(TBNAME,new String[]{
                // All existing columns
                "*",
                "rowid as uid",
                // generate reformatted date column named checkdate usable by date functions
                // i.e. converts dd/mm/yyyy to yyyy-mm-yy
                "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",7,4)||'-'||" +
                        "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",4,2)||'-'||" +
                        "substr( " + TaskContract.TaskEntry.COLUMN_DATE + ",1,2) AS " + TEMPPCOLNAME },
                // where clause to only include properly formatted dates and those who date is less
                // than or equaly to today's date
                TEMPPCOLNAME + "<= date('now') AND " +
                        "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",3,1) = '/' AND " +
                        "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",6,1) = '/'",
                null,null,null,null
                );

这就是说得到一个包含表(*)中所有列的Cursor,让Cursor有一个名为 uid 的列,它是 rowid 的别名,也是使Cursor有一个名为 checkdate 的列(根据TEMPCOLNAME的名称)。 checkdate是重新格式化的日期(现在像SQLite喜欢的yyyy-mm-dd)

WHERE子句(第三个参数)用于仅选择小于或等于第4个参数中定义的日期的日期,该参数将替换占位符。

WHERE参数还将选定的行限制为第3和第6位日期为 / 的行(仅作为预防措施)。

然后,更新非常简单,重要的是特定于单行(因此提取列 uid 的原因): -

    while (csr.moveToNext()) {
        ContentValues cv = new ContentValues();
        cv.put(TaskContract.TaskEntry.COLUMN_DATE,
                new SimpleDateFormat("dd/MM/yyyy").format(Calendar.getInstance().getTime()));
        db.update(TBNAME,cv,"rowid=?",new String[]{
                String.valueOf(csr.getLong(csr.getColumnIndex("uid")))}
                ); 
    }
    csr.close();

结合两者,你可以: -

public void updateDates2() {
    String TEMPPCOLNAME = "checkdate";
    Cursor csr = db.query(TaskContract.TaskEntry.TABLE_NAME,new String[]{
            // All existing columns
            "*",
            "rowid as uid",
            // generate reformatted date column named checkdate usable by date functions
            // i.e. converts dd/mm/yyyy to yyyy-mm-yy
            "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",7,4)||'-'||" +
                    "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",4,2)||'-'||" +
                    "substr( " + TaskContract.TaskEntry.COLUMN_DATE + ",1,2) AS " + TEMPPCOLNAME },
            // where clause to only include properly formatted dates and those who date is less
            // than or equaly to today's date
            TEMPPCOLNAME + "<= date('now') AND " +
                    "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",3,1) = '/' AND " +
                    "substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",6,1) = '/'",
            null,null,null,null
            );
    while (csr.moveToNext()) {
        ContentValues cv = new ContentValues();
        cv.put(TaskContract.TaskEntry.COLUMN_DATE,
                new SimpleDateFormat("dd/MM/yyyy").format(Calendar.getInstance().getTime()));
        if (
        db.update(TBNAME,cv,"rowid=?",new String[]{
                String.valueOf(csr.getLong(csr.getColumnIndex("uid")))}
                ) > 0) {
            Log.d("UPDT2","Row Updated OK.");
        } else {
            Log.d("UPDT2", "Update failed.");
        }
    }
    csr.close();
}

使用上述测试提供了以下结果: -

10-27 09:32:51.482 4259-4259/? D/EVENTDATA: Row 1 - Event Name is Event1 Starts on 01/03/2011 Ends on 2021-03-21
10-27 09:32:51.482 4259-4259/? D/EVENTDATA: Row 2 - Event Name is Event2 Starts on 14/08/2014 Ends on 2020-03-21
10-27 09:32:51.482 4259-4259/? D/EVENTDATA: Row 3 - Event Name is Event3 Starts on 26/10/2017 Ends on 2017-12-21
10-27 09:32:51.482 4259-4259/? D/EVENTDATA: Row 4 - Event Name is Event4 Starts on 28/10/2017 Ends on 2018-21-31
10-27 09:32:51.482 4259-4259/? D/EVENTDATA: Row 5 - Event Name is Event5 Starts on 01/01/2018 Ends on 2018-12-31
10-27 09:32:51.482 4259-4259/? D/EVENTDATA: Row 6 - Event Name is Event6 Starts on 27/10/2018 Ends on 2018-12-31
10-27 09:32:51.482 4259-4259/? D/EVENTDATA: Row 7 - Event Name is Event7 Starts on garbage Ends on 2018-12-31
10-27 09:32:51.483 4259-4259/? D/UPDT2: Extracted Row for Event Event1 StartDate Stored = 01/03/2011 Converted to = 2011-03-01
10-27 09:32:51.487 4259-4259/? D/UPDT2: Row Updated OK.
10-27 09:32:51.487 4259-4259/? D/UPDT2: Extracted Row for Event Event2 StartDate Stored = 14/08/2014 Converted to = 2014-08-14
10-27 09:32:51.491 4259-4259/? D/UPDT2: Row Updated OK.
10-27 09:32:51.491 4259-4259/? D/UPDT2: Extracted Row for Event Event3 StartDate Stored = 26/10/2017 Converted to = 2017-10-26
10-27 09:32:51.495 4259-4259/? D/UPDT2: Row Updated OK.
10-27 09:32:51.495 4259-4259/? D/EVENTDATA: Row 1 - Event Name is Event1 Starts on 27/10/2017 Ends on 2021-03-21
10-27 09:32:51.495 4259-4259/? D/EVENTDATA: Row 2 - Event Name is Event2 Starts on 27/10/2017 Ends on 2020-03-21
10-27 09:32:51.495 4259-4259/? D/EVENTDATA: Row 3 - Event Name is Event3 Starts on 27/10/2017 Ends on 2017-12-21
10-27 09:32:51.495 4259-4259/? D/EVENTDATA: Row 4 - Event Name is Event4 Starts on 28/10/2017 Ends on 2018-21-31
10-27 09:32:51.495 4259-4259/? D/EVENTDATA: Row 5 - Event Name is Event5 Starts on 01/01/2018 Ends on 2018-12-31
10-27 09:32:51.495 4259-4259/? D/EVENTDATA: Row 6 - Event Name is Event6 Starts on 27/10/2018 Ends on 2018-12-31
10-27 09:32:51.495 4259-4259/? D/EVENTDATA: Row 7 - Event Name is Event7 Starts on garbage Ends on 2018-12-31

前7行是上述运行之前的数据,后7是之后的数据。它们之间的6行形成更新本身(我删除了代码以生成Extracted Row .....,Converted to是checkdate的值,即重新格式化的日期)

但是,最好的方法可能是单个更新可以消除游标提取行的需要: -

public void updateDates() {
    Calendar c = Calendar.getInstance();
    SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
    String formattedDate = formatter.format(c.getTime());

    ContentValues cv = new ContentValues();
    cv.put(TaskContract.TaskEntry.COLUMN_DATE,formattedDate);

    String whereclause =
            " substr(" + TaskContract.TaskEntry.COLUMN_DATE +  ",7,4)||" +
                    " substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",4,2)||" +
                    " substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",1,2) " +
                    " <= date('now') " +
                    " AND substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",3,1) = '/'" +
                    " AND substr(" + TaskContract.TaskEntry.COLUMN_DATE + ",6,1) = '/'";
    db.update(TaskContract.TaskEntry.TABLE_NAME,cv,whereclause,null);
}

测试数据: -

10-27 11:25:52.331 5250-5250/? D/EVENTDATA: Row 1 - Event Name is Event1 Starts on 01/03/2011 Ends on 2021-03-21
10-27 11:25:52.331 5250-5250/? D/EVENTDATA: Row 2 - Event Name is Event2 Starts on 14/08/2014 Ends on 2020-03-21
10-27 11:25:52.331 5250-5250/? D/EVENTDATA: Row 3 - Event Name is Event3 Starts on 26/10/2017 Ends on 2017-12-21
10-27 11:25:52.331 5250-5250/? D/EVENTDATA: Row 4 - Event Name is Event4 Starts on 28/10/2017 Ends on 2018-21-31
10-27 11:25:52.331 5250-5250/? D/EVENTDATA: Row 5 - Event Name is Event5 Starts on 01/01/2018 Ends on 2018-12-31
10-27 11:25:52.331 5250-5250/? D/EVENTDATA: Row 6 - Event Name is Event6 Starts on 27/10/2018 Ends on 2018-12-31
10-27 11:25:52.332 5250-5250/? D/EVENTDATA: Row 7 - Event Name is Event7 Starts on garbage Ends on 2018-12-31
10-27 11:25:52.335 5250-5250/? D/EVENTDATA: Row 1 - Event Name is Event1 Starts on 27/10/2017 Ends on 2021-03-21
10-27 11:25:52.335 5250-5250/? D/EVENTDATA: Row 2 - Event Name is Event2 Starts on 27/10/2017 Ends on 2020-03-21
10-27 11:25:52.335 5250-5250/? D/EVENTDATA: Row 3 - Event Name is Event3 Starts on 26/10/2017 Ends on 2017-12-21
10-27 11:25:52.335 5250-5250/? D/EVENTDATA: Row 4 - Event Name is Event4 Starts on 28/10/2017 Ends on 2018-21-31
10-27 11:25:52.335 5250-5250/? D/EVENTDATA: Row 5 - Event Name is Event5 Starts on 01/01/2018 Ends on 2018-12-31
10-27 11:25:52.335 5250-5250/? D/EVENTDATA: Row 6 - Event Name is Event6 Starts on 27/10/2018 Ends on 2018-12-31
10-27 11:25:52.335 5250-5250/? D/EVENTDATA: Row 7 - Event Name is Event7 Starts on garbage Ends on 2018-12-31