0

私は一般的にAndroidとJavaの経験があまりないので、私の用語は間違っているかもしれません。そのために残念。

ともかく。LoaderManagerからデータを取得するListActivityがあります。LoaderManagerはContentProviderhttps : //github.com/jakenjarvis/Android-OrmLiteContentProviderを使用します。

セットアップ例とほぼ同じ方法で定義されたcontentUri(net.mydomain.app.listitems)を使用してデータをフェッチすると、すべてが正常に機能します。しかし、結合クエリからのデータが必要であり、そのクエリのURI(net.mydomain.app.listitems / items_joined)を追加しました。uriはContractクラスで定義され、itemsJoinedUriという名前が付けられています。このURIを使用する場合、新しいデータがテーブルに挿入されても、ビューのリストは更新されません。

ContentProviderクラスのonQueryメソッドで、「パターンコード」がitemsJoinedUriと一致する場合、カスタムクエリを実行します。他の副私は仕事をスーパーメソッドに渡します。

public class DataProvider extends OrmLiteSimpleContentProvider<DatabaseHelper> {

    @Override
    protected Class<DatabaseHelper> getHelperClass() {
        return DatabaseHelper.class;
    }

    @Override
    public boolean onCreate() {
        Controller = new MatcherController()
            .add(ListItem.class, SubType.Directory, "", Contract.ListItem.CONTENT_URI_PATTERN_MANY)
            .add(ListItem.class, SubType.Item, "#", Contract.ListItem.CONTENT_URI_PATTERN_ONE)
            .add(ListItem.class, SubType.Directory, "items_joined", Contract.ListItem.CONTENT_URI_PATTERN_WITH_ITEMS_JOINED)
            .initialize();
        return true;
    }

    @Override
    public Cursor onQuery(DatabaseHelper helper, MatcherPattern target, QueryParameters parameter) {
        Cursor result = null;
        //SQLiteQueryBuilder builder = new SQLiteQueryBuilder();

        switch(target.getPatternCode()) {
        case 310:
            String MY_QUERY = "SELECT items.name as name, listitems._id as _id FROM listitems INNER JOIN items ON items._id = listitems.item_id WHERE list_id = ?";
            SQLiteDatabase db = helper.getReadableDatabase();
            result = db.rawQuery(MY_QUERY, parameter.getSelectionArgs());
            break;
        default:
            result = super.onQuery(helper, target, parameter);
            break;
        }
        return result;
    }
}

関連する部分の私の契約の実装:

public class Contract {
    public static final String DATABASE_NAME = "mydatabase.db";
    public static final int DATABASE_VERSION = 1;

    public static final String AUTHORITY = "net.mydomain.app";
    .
    .
    .
    public static class ListItem implements BaseColumns {
        public static final String TABLENAME = "listitems";
        public static final String CONTENT_URI_PATH = TABLENAME;
        public static final String MIMETYPE_TYPE = TABLENAME;
        public static final String MIMETYPE_NAME = AUTHORITY + ".provider";

        // field info
        public static final String ITEM = "item_id";
        public static final String LIST = "list_id";
        public static final String QUANTITY = "quantity";

        // content uri pattern code
        public static final int CONTENT_URI_PATTERN_MANY = 300;
        public static final int CONTENT_URI_PATTERN_ONE = 301;
        public static final int CONTENT_URI_PATTERN_WITH_ITEMS_JOINED = 310;

        // Refer to activity.
        public static final Uri contentUri = new Uri.Builder()
            .scheme(ContentResolver.SCHEME_CONTENT)
            .authority(AUTHORITY)
            .appendPath(CONTENT_URI_PATH)
            .build();

        public static final Uri itemsJoinedUri = new Uri.Builder()
            .scheme(ContentResolver.SCHEME_CONTENT)
            .authority(AUTHORITY)
            .appendPath(CONTENT_URI_PATH)
            .appendPath("items_joined")
            .build();
    }
}

ListActivityのonCreateLoaderメソッドはここにあります。使用したいのにリストが正しく更新されていないものはコメントアウトされています。

//  @Override
//  public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
//      String[] selectArgs = { "" + list_id };
//      Uri baseUri = Contract.ListItem.itemsJoinedUri;
//      return new CursorLoader(this, baseUri, null, null, selectArgs, null);
//  }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
        String select = "( " + Contract.ListItem.LIST + " = 2 )";
        Uri baseUri = Contract.ListItem.contentUri;
        String[] projection = new String[] {
                Contract.ListItem._ID,
                Contract.ListItem.LIST
        };
        return new CursorLoader(this, baseUri, projection, select, null, null);
    }

リストの新しいアイテムは、コードを使用して別のアクティビティに挿入されますgetContentResolver().insert(Contract.ListItem.contentUri, values);。そのアクティビティは、階層内でListActivityよりも1ステップ深いので、戻るボタンを使用してListActivityに戻ることができます。これは、リストが更新されていないことを確認するときです。

したがって、データはcontentUriを使用して挿入されますが、自分のitemsJoinedUriを使用して読み取られます。それがここでの問題でしょうか?

編集

リストから行を削除するための単純なクリックリスナーを追加しました。これはcontentUriを使用し、削除後にリストが自動的に更新されます。したがって、別のアクティビティからリストに戻るときにリストが更新されないという問題は、ListActivityのライフサイクルの実装の誤りに関連している可能性があると思います。

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    String[] args = { "" + id};
    getContentResolver().delete(Contract.ListItem.contentUri, "_id = ?", args);
}
4

2 に答える 2

1

問題はライフサイクル管理にありました。適切なonRestart()の実装がありませんでした。これを追加すると、すべてが機能します。

@Override
public void onRestart() {
    super.onRestart();
    getLoaderManager().getLoader(0).forceLoad();
}
于 2013-02-09T01:18:09.367 に答える
0

コメントアウトした部分では、選択引数のみを送信し、選択文字列は送信していません。選択引数を単独で使用することはできません。たとえば、選択文字列も設定する必要があります。

return new CursorLoader(this, baseUri, null, "_id = ?", selectArgs, null);

それは動作しますか?

于 2013-02-09T00:03:41.633 に答える