我有一个Fragment
List类(如下所示),用于使用Content Provider
显示本地SQLite数据库中的值。
public static ContentResolver resolver;
Uri uri;
AsyncQueryHandler handler;
public static SimpleCursorAdapter adapter;
private Cursor localCursor;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
resolver = this.getActivity().getContentResolver();
uri = Uri
.parse("content://com.n00111715.messengerlist.model.MessageContentProvider/messages");
handler = new AsyncQueryHandler(resolver) {
public void onQueryComplete(int token, Object cookie, Cursor cursor) {
MessageListFragment.this.onQueryComplete(cursor);
}
};
handler.startQuery(0, null, uri, null, null, null, null);
}
public void onQueryComplete(Cursor cursor) {
// store the cursor values
localCursor = cursor;
String[] from = new String[] { "_id", "reciever", "sender", "subject",
"date", "message" };
int[] to = new int[] { R.id.hidden_id_field, R.id.hidden_to_field,
R.id.list_item_message_from_textview,
R.id.list_item_message_subject_textview,
R.id.list_item_message_date_textview,
R.id.list_item_message_content_textview };
// create a simple cursor adapter that used the cursor from the
// database, and maps the values
// to the textviews in the list items that make up the list fragment
adapter = new SimpleCursorAdapter(this.getActivity(),
R.layout.list_item_message, cursor, from, to, 0);
// set this as this list fragments adapter
setListAdapter(adapter);
}
public void onListItemClick(ListView l, View v, int position, long id) {
String currentId = String.valueOf(id);
int i = 0;
String[] values = new String[6];
// loop through the cursor object
localCursor.moveToFirst();
while (localCursor.isAfterLast() == false) {
// extract this row values for the id column, if the match the
// selected id
if (localCursor.getString(0).equals(currentId)) {
// loop through the values of the full row
for (int j = 0; j < values.length; j++) {
// add these values to the values string array
values[j] = localCursor.getString(j);
}
}
i++;
localCursor.moveToNext();
}
// create new intent
Intent intent = new Intent(getActivity(), ViewingMessageActivity.class);
// add the selected messages values into extras
intent.putExtra("values", values);
// start the ne activity
startActivity(intent);
}
当我在列表中选择一个项目时,会显示Activity
(下方)。
// variable for the UI elements
Button deleteButton, saveButton, forwardButton;
EditText editTextFrom, editTextSubject, editTextContent;
//MessageListFragment mlf;
String[] values;
Intent intent;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the layout file for this activity
setContentView(R.layout.viewing_fragment_layout);
// get the the intent
intent = getIntent();
// retrieve the string array from extras
values = intent.getStringArrayExtra("values");
Log.d("this is my array", "values: " + Arrays.toString(values));
getReferences();
populateUIFields();
}
private void populateUIFields() {
// insert message values into the text fields
editTextFrom.setText(values[2]); // from
editTextSubject.setText(values[3]); // subject
editTextContent.setText(values[4]); // content
}
private void getReferences() {
// get references to the ui elements
deleteButton = (Button) findViewById(R.id.deleteButton);
saveButton = (Button) findViewById(R.id.saveButton);
forwardButton = (Button) findViewById(R.id.forwardButton);
editTextFrom = (EditText) findViewById(R.id.editTextFrom);
editTextSubject = (EditText) findViewById(R.id.editTextSubject);
editTextContent = (EditText) findViewById(R.id.editTextContent);
// add click listeners to each button
deleteButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String whereClause = "_id = " + values[0];
ContentResolver resolver = getApplicationContext()
.getContentResolver();
Uri uri = Uri
.parse("content://com.n00111715.messengerlist.model.MessageContentProvider/messages");
AsyncQueryHandler handler = new AsyncQueryHandler(resolver) {
public void onDeleteComplete(int token, Object cookie,
int result) {
ViewingMessageActivity.this.onDeleteComplete(result);
}
};
handler.startDelete(0, null, uri, whereClause, null);
}
});
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
values[2] = editTextFrom.getText().toString();
values[3] = editTextSubject.getText().toString();
values[4] = editTextContent.getText().toString();
ContentValues row = new ContentValues();
row.put("reciever", values[1]);
row.put("sender", values[2]);
row.put("subject", values[3]);
row.put("message", values[4]);
row.put("date", values[5]);
String whereClause = "_id = " + values[0];
ContentResolver resolver = getApplicationContext()
.getContentResolver();
Uri uri = Uri
.parse("content://com.n00111715.messengerlist.model.MessageContentProvider/messages");
AsyncQueryHandler handler = new AsyncQueryHandler(resolver) {
public void onUpdateComplete(int token, Object cookie,
int result) {
ViewingMessageActivity.this.onSaveComplete(result);
}
};
handler.startUpdate(0, null, uri, row, whereClause, null);
}
});
}
protected void onDeleteComplete(int result) {
Toast.makeText(getApplicationContext(), "message deleted",
Toast.LENGTH_LONG).show();
//return to the list fragment and refresh the list
}
protected void onSaveComplete(int result) {
Toast.makeText(getApplicationContext(), "message saved",
Toast.LENGTH_LONG).show();
//return to the list fragment and refresh the list
}
当从这个类里面更新数据库时,我想返回列表片段(处理当前活动?)并刷新列表以显示数据的任何变化。
我想我需要为数据库创建一个新查询,并为此列表片段创建一个新的适配器。我不确定如何在观看活动中进行此操作。
我找到了this answer that is similar to my problem,但我无法让它发挥作用。
这就是Content Provider
的样子。
public static final String AUTHORITY = "com.n00111715.messengerlist.model.MessageContentProvider";
private static final UriMatcher sUriMatcher;
private static final int MESSAGE_COLLECTION_URI_INDICATOR = 1;
private static final int SINGLE_MESSAGE_URI_INDICATOR = 2;
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + MessageTableGateway.TABLE_MESSAGES);
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.n00111715.messengerlist.model.message";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.n00111715.messengerlist.model.message";
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(AUTHORITY, MessageTableGateway.TABLE_MESSAGES,
MESSAGE_COLLECTION_URI_INDICATOR);
sUriMatcher.addURI(AUTHORITY,
MessageTableGateway.TABLE_MESSAGES + "/#",
SINGLE_MESSAGE_URI_INDICATOR);
}
private MessageTableGateway mMessageTableGateway;
private ContentResolver mContentResolver;
@Override
public boolean onCreate() {
Context context = getContext();
mContentResolver = context.getContentResolver();
MessengerListOpenHelper helper = MessengerListOpenHelper
.getInstance(context);
SQLiteDatabase db = helper.getWritableDatabase();
mMessageTableGateway = MessageTableGateway.getInstance(db);
return true;
}
@Override
public int update(Uri uri, ContentValues values, String whereClause,
String[] whereArgs) {
int count;
switch (sUriMatcher.match(uri)) {
case MESSAGE_COLLECTION_URI_INDICATOR:
count = mMessageTableGateway.update(values, whereClause, whereArgs);
break;
case SINGLE_MESSAGE_URI_INDICATOR:
String id = uri.getPathSegments().get(1);
String where = MessageTableGateway.COLUMN_ID + " = " + id;
if (TextUtils.isEmpty(whereClause)) {
whereClause = where;
} else {
whereClause = where + " AND " + where;
}
count = mMessageTableGateway.update(values, whereClause, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
mContentResolver.notifyChange(uri, null, false);
return count;
}
@Override
public int delete(Uri uri, String whereClause, String[] whereArgs) {
int count;
switch (sUriMatcher.match(uri)) {
case MESSAGE_COLLECTION_URI_INDICATOR:
count = mMessageTableGateway.delete(whereClause, whereArgs);
break;
case SINGLE_MESSAGE_URI_INDICATOR:
String id = uri.getPathSegments().get(1);
String where = MessageTableGateway.COLUMN_ID + " = " + id;
if (TextUtils.isEmpty(whereClause)) {
whereClause = where;
} else {
whereClause = where + " AND " + where;
}
count = mMessageTableGateway.delete(whereClause, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
mContentResolver.notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (sUriMatcher.match(uri)) {
case MESSAGE_COLLECTION_URI_INDICATOR:
return CONTENT_TYPE;
case SINGLE_MESSAGE_URI_INDICATOR:
return CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
Uri insertedMessageUri;
if (sUriMatcher.match(uri) != MESSAGE_COLLECTION_URI_INDICATOR) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
long id = mMessageTableGateway.insert(values);
if (id > 0) {
insertedMessageUri = ContentUris.withAppendedId(CONTENT_URI, id);
} else {
throw new SQLException("Failed to insert message into " + uri);
}
mContentResolver.notifyChange(insertedMessageUri, null);
return insertedMessageUri;
}
@Override
public Cursor query(Uri uri, String[] columns, String whereClause,
String[] whereArgs, String sortOrder) {
Cursor c;
switch(sUriMatcher.match(uri)) {
case MESSAGE_COLLECTION_URI_INDICATOR:
c = mMessageTableGateway.query(columns, whereClause, whereArgs, null, null, sortOrder, null);
break;
case SINGLE_MESSAGE_URI_INDICATOR:
String id = uri.getPathSegments().get(1);
String where = MessageTableGateway.COLUMN_ID + " = " + id;
if (TextUtils.isEmpty(whereClause)) {
whereClause = where;
} else {
whereClause = whereClause + " AND " + where;
}
c = mMessageTableGateway.query(columns, whereClause, whereArgs, null, null, sortOrder, null);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
c.setNotificationUri(mContentResolver, uri);
return c;
}
答案 0 :(得分:0)
使用与列表片段查询的uri相同的uri添加notifyChange调用。它可能是没有添加特定行Id的更新uri。
答案 1 :(得分:0)
如果您想自动执行此操作,则应在活动中使用CursorLoader
。有很多使用这种方法的教程。
我推荐你这个教程:http://www.vogella.com/tutorials/AndroidSQLite/article.html(在你的案例中最有趣的是9,但我建议你仔细阅读以了解整体情况)
我将指出最重要的一点:
ListFragment
类ListView
的{{1}}必须具有此ID ListFragment
@android:/id_list
,LoaderManager.LoaderCallbacks<Cursor>
和onCreateLoader
onLoadFinished
及其3种方法
onLoaderReset
SimpleCursorAdapter
因为getLoaderManager().initLoader(your_id, null, this);
是您的应用中定义的唯一your_id
希望有所帮助