在onClick之后正确更新RealmModel而不阻止Android中的用户界面

时间:2016-08-11 19:49:14

标签: android android-recyclerview realm realm-list

我有RecyclerView来显示Realm数据库中的项目。 为此,我基于realm-android-adapters实施了RealmRecyclerViewAdapter,其中传递了OrderedRealmCollection。 为此,我使用findAllAsync()

加载数据
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会将任何异步查询转换为同步查询以保持一致。改为使用异步写入。

是否有可能在不引入延迟或阻止动画显示的情况下完全异步更新项目?

2 个答案:

答案 0 :(得分:2)

当您的Realm自动更新时,

RealmRecyclerViewAdapter会调用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();
                         }
                     }
                 });
             }
        });
    }
}

答案 1 :(得分:0)

在后台线程上执行此操作。我建议使用经典的Thread.class .Start动画outisde new Thread,并通过UI Thread上的回调将其解除。

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();