想通过 Android 中的数据库在列表视图中添加标题和日期

Want to add Title and Date in listview through database in Android

我想在 ListView 中添加任务标题和日期,但使用以下代码它只显示日期(来自 COLUMN_DATE)并且根本不显示标题。标题未加载,但正在加载日期。

private void updateUI() {
    ArrayList<String> taskList = new ArrayList<>();
    ArrayList<String> taskList1 = new ArrayList<>();
    SQLiteDatabase db = mHelper.getReadableDatabase();
    Cursor cursor = db.query(TaskContract.TaskEntry.TABLE_NAME,
            new String[]{TaskContract.TaskEntry._ID,
                    TaskContract.TaskEntry.COL_TASK_TITLE,
                    TaskContract.TaskEntry.COLUMN_DATE,
                    },
            null, null, null, null, null);
    while (cursor.moveToNext()) {
        int idx = cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
        taskList.add(cursor.getString(idx));
        int idx1 = cursor.getColumnIndex(TaskContract.TaskEntry.COLUMN_DATE);
        taskList1.add(cursor.getString(idx1));

    }

    if   (mAdapter == null) {
        mAdapter = new ArrayAdapter<>(this, R.layout.item_todo, R.id.task_title, taskList);
        mAdapter1 = new ArrayAdapter<>(this, R.layout.item_todo, R.id.dateTextView, taskList1);
        mTaskListView.setAdapter(mAdapter);
        mTaskListView1.setAdapter(mAdapter1);
    }
    else {
        mAdapter.clear();
        mAdapter.addAll(taskList);
        mAdapter.notifyDataSetChanged();

    }
    cursor.close();
    db.close();
}

我认为您的问题是您使用的是相同的布局,它们将具有相同的 ID,并且没有什么可以区分要使用的(实际上可能不是真的,因为它很可能先到先得,但最终结果会令人困惑)。

也许想象一下同卵双胞胎都叫弗雷德

我建议使用两个具有唯一 ID 的布局,例如有另一个名为 item_todo1 的布局,id 为 task_title1dateTextView1.

然后替换

mAdapter1 = new ArrayAdapter<>(this, R.layout.item_todo, R.id.dateTextView, taskList1);

with(即使用第二个布局和另一个 id)

mAdapter1 = new ArrayAdapter<>(this, R.layout.item_todo1, R.id.dateTextView1, taskList1);

您还需要获取 dateTextView1task_title 的 ID。

注意!这假设您想要 2 个 ListView,您可能认为您需要 2

也许您想要的是一个同时显示日期和标题的列表,在这种情况下,以下内容可能会起作用,这可能是最简单的解决方案(我想我理解为什么您有 2 个列表并且它是到期的到拥有多个项目的复杂性)。

此方法将通过 SimpleCursorAdapter 直接使用光标,而不是 ArrayAdapter,后者不仅不需要中间数组,而且更容易处理列表项中的多个元素。唯一的缺点(即使是缺点)是游标保持并且必须保持打开状态,因此数据库也必须保持打开状态(解决方案是在活动的 onDestroy 方法中关闭)。

除 DBHelper 之外的完整代码(已测试)(注意这也会生成一些用于测试的行)是:-

public class MainActivity extends AppCompatActivity {


    SimpleCursorAdapter mAdapter;
    SQLiteDatabase mDB;
    DBHelper mDBHelper;
    Cursor mCursor;
    ListView mTaskListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHelper = new DBHelper(this);
        mDB = mDBHelper.getDB();
        mTaskListView = (ListView) findViewById(R.id.tasklistview);

        // Add some tasks for testing
        for (int i = 0; i < 5; i++) {
            mDBHelper.addRow("TITLE" + String.format("%03d", i), Long.toString(System.currentTimeMillis()));
        }
        UpdateUI();
    }

    private void UpdateUI() {

        mCursor = mDB.query(DBHelper.TBNAME,
                new String[]{"rowid AS _id", DBHelper.COL_TASK_TITLE, DBHelper.COLUMN_DATE},
                null, null, null, null, null);
        mAdapter = new SimpleCursorAdapter(this, R.layout.item_todo, mCursor,
                new String[]{DBHelper.COL_TASK_TITLE, DBHelper.COLUMN_DATE},
                new int[]{R.id.task_title, R.id.date_textView},
                0
        );

        mTaskListView.setAdapter(mAdapter);
    }
}

调整上面的代码(注意未经测试所以可能有拼写错误)

你只需要考虑需要定制的UpdateUI方法(未测试,因此可能会有拼写错误):-

private void UpdateUI() {

            SQLiteDatabase db = mHelper.getReadableDatabase();
    Cursor cursor = db.query(TaskContract.TaskEntry.TABLE_NAME,
            new String[]{TaskContract.TaskEntry._ID,
                    TaskContract.TaskEntry.COL_TASK_TITLE,
                    TaskContract.TaskEntry.COLUMN_DATE,
                    },
            null, null, null, null, null);
            mAdapter = new SimpleCursorAdapter(this, 
                R.layout.item_todo, 
                mCursor,
                // Displayed data source column names                
                new String[]{
                    TaskContract.TaskEntry.COL_TASK_TITLE, 
                    TaskContract.TaskEntry.COLUMN_DATE},
                // respective layout id's for the displayed data
                new int[]{
                    R.id.task_title, 
                    R.id.date_textView},
                    0
            );

            mTaskListView.setAdapter(mAdapter);
        }

注意!!!_id 是游标适配器所必需的,例如,如果列名等同于ID(没有下划线前缀)则应用程序将失败。解决方案在查询中使用 'ID AS _id' 或 rowid AS _id 或永久更改列名称。

其他注意事项:-

这里有一些代码(经过测试但未改编,所以使用我的测试代码)来展示 Cursor adpater 的另一个优势,即对数据库执行操作的简便性(在这些示例中删除行):-

private void implementListViewListener() {

    // ONITEMCLICK LISTENER
    mTaskListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            // DO YOUR ONCLICK STUFF HERE
            // NOTE l is the _id of the row e.g. to delete a task
            mDB.delete(DBHelper.TBNAME,DBHelper.COLUMN_ID + "=?",new String[]{Long.toString(l)});
            // To then refresh the ListView
            // a) get the refreshed data(Cursor) from the database
            mCursor = mDB.query(DBHelper.TBNAME,
                    new String[]{"rowid AS _id", DBHelper.COL_TASK_TITLE, DBHelper.COLUMN_DATE},
                    null, null, null, null, null);
            mAdapter.swapCursor(mCursor);
        }
    });

    // ONITEMLONGCLICK LISTENER (NOTE returns boolean should very likely/mostly return TRUE)
    mTaskListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
            // DO YOUR ONCLICK STUFF HERE
            // NOTE l is the _id of the row e.g. to delete a task
            mDB.delete(DBHelper.TBNAME,DBHelper.COLUMN_ID + "=?",new String[]{Long.toString(l)});
            // To then refresh the ListView
            // a) get the refreshed data(Cursor) from the database
            mCursor = mDB.query(DBHelper.TBNAME,
                    new String[]{"rowid AS _id", DBHelper.COL_TASK_TITLE, DBHelper.COLUMN_DATE},
                    null, null, null, null, null);
            mAdapter.swapCursor(mCursor);
            return true;
        }
    });
}

要使用上面的代码,您只需在 activity.

中编码 implementListViewListener();