2

RecyclerViewデータベースのアイテムを表示する がありますRealm。そうするために、渡されたrealm-android-adaptersRealmRecyclerViewAdapterに基づいて実装しました。このために、データをロードしますOrderedRealmCollectionfindAllAsync()

realm.where(Entry.class).findAllAsync()

OnClickListenerユーザーがリストをスクロールすると、いくつかのエントリを「お気に入り」にするオプションがあります。これは、「お気に入り」ボタンに通常の方法で実装しました。

ユーザーがボタンをクリックするたびに、エントリの「お気に入り」ブール値を更新したいと思います。ユーザーがクリックすると、小さなアニメーションがボタンに表示されます。

このために、私は悲しいことに間違ったスレッド例外を与える次のことを試しました:

realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        entry.setLiked(!entry.isLiked());
    }
});

別の方法として、動作する通常の方法で試しましたexecuteTransactionが、アニメーションが表示されないようにしました。

realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        entry.setLiked(!entry.isLiked());
    }
});

興味深い追加として、これにより次のログが得られます。

非同期クエリとローカル書き込みを混在させることは避ける必要があります。Realm は、一貫性を保つために非同期クエリを同期クエリに変換します。代わりに非同期書き込みを使用してください。

ラグを導入したり、アニメーションの表示を妨げたりすることなく、アイテムを完全に非同期に更新する可能性はありますか?

4

2 に答える 2

2

RealmRecyclerViewAdapterRealm が自動更新されるときに呼び出さadapter.notifyDataSetChanged()れるため、レイアウト アニメーションは呼び出されません。

実際に変更を行うことについては、

public class EntryViewHolder extends RecyclerView.ViewHolder {
    @BindView(R.id.entry_favorite)
    Button favButton;

    public EntryViewHolder(View view) {
        super(view);
        ButterKnife.bind(this, view);
    }

    public void bind(Entry entry) {
        final long entryId = entry.getId();
        favButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
                 realm.executeTransactionAsync(new Realm.Transaction() {
                     @Override
                     public void execute(Realm realm) {
                         Entry entry = realm.where(Entry.class)
                                            .equalTo("id", id)
                                            .findFirst();
                         if(entry != null) {
                             entry.deleteFromRealm();
                         }
                     }
                 });
             }
        });
    }
}
于 2016-08-13T06:17:09.167 に答える
0

これをバックグラウンド スレッドで実行します。従来の Thread.class を使用することをお勧めします。新しいスレッドの外側でアニメーションを開始し、UI スレッドのコールバックを介して終了します。

Realm realm = Realm.getInstance(..);
realm.beginTransaction();
YourClass yourClassInstance = realm.where(YourClass.class)
        .equalTo(..)
        .findFirst();
if(yourClassInstance != null){
   yourClassInstance.setLiked(!yourClassInstance.getLiked());
}else{
   yourClassInstance = realm.createObject(YourClass.class);
   yourClassInstance.setLiked(whateverYouWant);
}
realm.commitTransaction();
于 2016-08-11T20:29:07.147 に答える