想通过 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_title1
和 dateTextView1
.
然后替换
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);
您还需要获取 dateTextView1
和 task_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();
我想在 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_title1
和 dateTextView1
.
然后替换
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);
您还需要获取 dateTextView1
和 task_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();