在安卓中过滤Realm对象

4

我已经开始使用 Realm,一切都运行良好,几乎都很顺利。

我正在使用 MultiAutoCompleteTextView 来选择一些用户(RealmObject)。

以下是我的过滤器(适配器的内部类):

private class UserFilter extends Filter {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults filterResults = new FilterResults();
        if (constraint == null || constraint.length() == 0) {
            filterResults.values = mUsers;
            filterResults.count = mUsers.size();
        } else {
            final String lastToken = constraint.toString().toLowerCase();
            final List<User> list = new ArrayList<>();

            RealmQuery<User> query = realm.where(User.class);
            query.contains("nickname", lastToken, false);
            RealmResults<User> result = query.findAll();
            list.addAll(result);


            filterResults.values = list;
            filterResults.count = list.size();
        }
        return filterResults;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        mFilteredUsers = (List<User>) results.values;
        if (results.count > 0) {
            notifyDataSetChanged();
        } else {
            notifyDataSetInvalidated();
        }
    }

在我的适配器中: 在getView方法中:

EGCUser user = getItem(position);

holder.mName.setText(user.getNickname());

用户是无效的对象,我尝试了很多不同的方法,但都失败了。因此,我想知道该怎么做才能实现它。我有很多线程问题,所以可能是内部类的问题?

谢谢。

编辑:在这种情况下,我应该在哪里执行Realm.getInstance()?

现在,我将上下文传递给我的适配器,并在适配器的构造函数中执行它,并将realm对象存储在变量中。

编辑2:我让它工作了,但我不知道这是我们应该做的方式:

在我的performFiltering中,我做了这个:

((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    final List<User> list = new ArrayList<>();
                    Realm realm = Realm.getInstance(mContext);
                    RealmQuery<User> query = realm.where(User.class);
                    query.contains("nickname", lastToken, false);
                    RealmResults<User> result1 = query.findAll();
                    list.addAll(result1);

                    filterResults.values = list;
                    filterResults.count = list.size();

                }
            });

但我会为此开放反馈。

2个回答

3

我是Realm的Christian。很遗憾,由于我们的线程限制(Filter需要在后台线程上执行),Realm目前不支持Filter类。但我们已经将其列入待办事项,并可以在此处跟踪进度:https://github.com/realm/realm-android-adapters/issues/79

在那之前,您有两个选择:

1)在UI线程上执行过滤操作。如果Realm中没有太多条目或查询相对简单,则可能会发现这足够快。我们已经有使用Realm的键盘应用程序采用了这种方式。

2)不返回适当的Realm对象,而是从performFiltering()方法中读取所需的任何数据以显示并返回它们。


你好,Christian,感谢回答,正如你所看到的,我最终在UI线程上执行了它 :D 此外,我可能已经发现了一个错误,最好的报告方式是什么?这里?github? - Neodigi
GitHub是最好的选择。非常感谢。 - Christian Melchior
@Néodigi,你能分享一下如何在UI线程上执行过滤吗? - Vaclovas Rekašius Jr.

1
我实现了一个解决方案。我所做的筛选器负责帮助 AutocompleteTextView。这个策略包括创建一个封装领域对象字段的包装类。此外,它还应该包含主键,以便您可以检索完整的对象。
下面是“包装器”类的示例:
public class RealmWrapper{

  private long oid;
  private String representation;

  public RealmWrapper(long oid, String representation) {
    this.oid = oid;
    this.representation = representation;
  }

  public long getOid() {
    return this.oid;
  }

  public void setOid(long oid) {
    this.oid = oid;
  }

  public String getRepresentation() {
    return representation;
  }

  public void setRepresentation(String representation) {
    this.representation = representation;
  }

  @Override
  public String toString() {
    return representation;
  }
}

当您从Realm中提取实体时,将结果复制到包装器中:
 List<RealmWrapper> newObjects = new ArrayList<>();
 for( User entity : (RealmResults<User>) queryResults ){
     newObjects.add( new RealmWrapper(entity.getOid(), entity.getName()) );
 }

最后,当您从视图中获取RealmViewAdapter时,您可以检索原始对象:
User user = Realm.getInstance(context)
          .where(User.class)
          .contains("oid",adapter.getOid)
          .firstResult(); 

我希望这能帮助你!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接