我已经在网上浏览了2天并尝试了很多东西,但似乎无法弄清楚这有什么问题.
我仍然相当熟悉Android的发展,所以我可能错过了一些明显的东西.
我有一个应用程序女巫正在使用sqllite数据库存储一些数据和这个概念证明的列表在列表视图中显示.我可以在列表中添加项目,删除它们.
到现在为止还挺好.我遇到的问题是当我而不是删除更新数据库中名为“已删除”的列并将其设置为1然后让适配器更新列表.似乎没有用.
如果我使用删除语句,它的工作原理.它更新,一切都很好,但我想在数据库中删除已删除的项目,但不显示它们(所以基本上“隐藏”项目)
如果我检查数据库,更新本身会成功更改列和所有内容,所以我想这是一个刷新问题,因为适配器不会重新查询数据库或那个方向的东西
Listview Loader:
public void fillData() {
if(lw.getAdapter() == null){
// Fields from the database (projection)
// Must include the _id column for the adapter to work
String[] from = new String[] { TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_ID};
String where = TodoTable.COLUMN_DELETED + " = ?";
Cursor cursor = getContentResolver().query(TodoContentProvider.CONTENT_URI,from,where,new String[] {"0"},null);
// Fields on the UI to which we map
int[] to = new int[] { R.id.label };
adapter = new SimpleCursorAdapter(this, R.layout.todo_row, cursor, from,
to, 0);
Log.v("Count",Integer.toString(cursor.getCount()));
lw.setAdapter(adapter);
}
else
adapter.notifyDataSetChanged();
}
删除功能
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case DELETE_ID:
/* Code for actual delete
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
Uri uri = Uri.parse(TodoContentProvider.CONTENT_URI + "/"
+ info.id);
getContentResolver().delete(uri, null, null);
fillData();
*/
/* Code for update and hide */
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
Uri uri = Uri.parse(TodoContentProvider.CONTENT_URI + "/"
+ info.id);
ContentValues values = new ContentValues();
values.put(TodoTable.COLUMN_DIRTY, 1);
values.put(TodoTable.COLUMN_DELETED, 1);
getContentResolver().update(uri,values,null,null);
fillData();
return true;
}
return super.onContextItemSelected(item);
}
如果我将日志放入ContentProvider的查询函数,它实际上不会触发.
关于如何解决这个问题的任何建议?
如果我使用adapter.swapCursor(cursor);它工作正常只是不知道这是否是这样做的正确方法.
public void fillData() {
// Fields from the database (projection)
// Must include the _id column for the adapter to work
String[] from = new String[] { TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_ID};
String where = TodoTable.COLUMN_DELETED + " = ?";
Cursor cursor = getContentResolver().query(TodoContentProvider.CONTENT_URI,from,where,new String[] {"0"},null);
// Fields on the UI to which we map
int[] to = new int[] { R.id.label };
if(lw.getAdapter() == null){
adapter = new SimpleCursorAdapter(this, R.layout.todo_row, cursor, from,
to, 0);
Log.v("Count",Integer.toString(cursor.getCount()));
lw.setAdapter(adapter);
}
else
{
adapter.swapCursor(cursor);
}
}
Ty的帮助
解决方法:
使用adapter.swapCursor(光标)是正确的,所以你几乎在回答你自己的问题.
您的第一段代码不起作用,因为在数据库更新后调用fillData()时,只需调用adapter.notifyDataSetChanged()并且数据集实际上没有更改,因为游标是相同的.游标是对数据库中行的引用,更新底层数据库不会刷新游标.您的第二段代码会刷新光标并将新光标交换到适配器(这也会触发对其绑定的视图的更新).
更常见的编码方式是:
将此界面添加到您的活动中:
public class MyActivity extends Activity implementsLoaderManager.LoaderCallbacks<Cursor>
在onCreate中,设置适配器(注意此时光标为空):
String[] from = new String[] { TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_ID};
int[] to = new int[] { R.id.label };
adapter = new SimpleCursorAdapter(this, R.layout.todo_row, null, from, to, 0); //Note that the cursor is null
lw.setAdapter(adapter);
启动加载器:
getLoaderManager().initLoader(0, null, this);
这会在后台线程中调用onCreateLoader(因此,如果您的查询长时间运行,则不会阻止UI线程).完成后,在UI线程上调用onLoadFinished,您可以在其中交换新光标.
执行删除或更新后,重新启动加载程序:
getLoaderManager().restartLoader(0, null, this);
这将调用onLoaderReset,它从适配器中删除现有游标,然后再次调用onCreateLoader以交换新的游标.
最后添加以下方法:
public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
String[] from = new String[] { TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_ID};
String where = TodoTable.COLUMN_DELETED + " = ?";
Loader<Cursor> loader = new CursorLoader(this, TodoContentProvider.CONTENT_URI, from, where, new String[] {"0"}, null);
return loader;
}
public void onl oadFinished(Loader<Cursor> loader, Cursor cursor)
{
adapter.swapCursor(cursor);
}
public void onl oaderReset(Loader<Cursor> loader)
{
adapter.swapCursor(null);
}