问题
So i've started to use Realm and everything works fine, well almost everything.
I'm using a MultiAutoCompleteTextView to select some user (RealmObject)
so here goes:
this is my Filter( inner class of my adapter)
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();
}
}
And in my adapter: in the getView method:
EGCUser user = getItem(position);
holder.mName.setText(user.getNickname());
user is an invalid object, i've been trying so many different thing and everything failed. So I'm wondering what can I do the achieved that. I've got a lot of thread issue so maybe it's a problem with the inner class ?
Thanks
EDIT: in this situation, where am I supposed to do the Realm.getInstance()?
Right now, I pass a context in my adapter and i'm doing it in the constructor of the adapter, and i'm stocking the realm object in a variable.
EDIT2: I got it to work but I don't know if this is how we're supposed to do:
In my performFiltering I did this:
((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();
}
});
But i'll this open for feedback.
回答1:
Christian from Realm here. Unfortunately Realm currently doesn't support the Filter class due to our Thread restrictions (and Filter does it's job on a background thread). We have it on our TODO however and you can follow progress here: https://github.com/realm/realm-android-adapters/issues/79
Until then you have two options:
1) Perform the filtering the the UI thread. If you don't have that many items in Realm or the query is relative simple, you will probably find that this is fast enough. We already have keyboard apps using Realm that does it this way.
2) Instead of returning proper Realm objects, read whatever data you need to display and return that from the performFiltering() method instead.
回答2:
I implemented a solution. The filter I did was responsible of help an AutocompleteTextView. The strategy consists of create a wrapper class that encapsulates the fields of the realm objects you want to show. Also, it should contains the primary key so then you can retrieve the full object.
This is an example of the "wrapper" class:
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;
}
}
And when you extract the entities from Realm you copy the results to the wrapper:
List<RealmWrapper> newObjects = new ArrayList<>();
for( User entity : (RealmResults<User>) queryResults ){
newObjects.add( new RealmWrapper(entity.getOid(), entity.getName()) );
}
And finally, when you got the RealmViewAdapter from the view, you retrieve the original object:
User user = Realm.getInstance(context)
.where(User.class)
.contains("oid",adapter.getOid)
.firstResult();
I hope this help you!
来源:https://stackoverflow.com/questions/30162431/filtering-realm-object-in-android