如何使用其他Activity中的内容提供程序刷新ListFragment?

时间:2014-01-06 17:33:40

标签: java android android-listview android-fragments refresh

我有一个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;
}

2 个答案:

答案 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_listLoaderManager.LoaderCallbacks<Cursor>onCreateLoader
  • 中的说明实施此界面onLoadFinished及其3种方法
  • 根据需要使用onLoaderReset
  • 调用此方法非常重要SimpleCursorAdapter因为getLoaderManager().initLoader(your_id, null, this);是您的应用中定义的唯一your_id

希望有所帮助