问题
I am trying to setup an AuotoCompleteTextview (in my MainActivity) where data is fetched from Realm database. So I'm using an adapter as following:
public abstract class FilterableRealmBaseAdapter<T extends RealmObject> extends ArrayAdapter<T> implements Filterable {
private final RealmResults<T> mRealmObjectList;
private List<T> mResults;
public FilterableRealmBaseAdapter(Context context, @LayoutRes int layout, RealmResults<T> realmObjectList) {
super(context, layout);
mRealmObjectList = realmObjectList;
}
@Override
public int getCount() {
return mResults == null ? 0 : mResults.size();
}
@Override
public T getItem(int position) {
return mResults == null ? null : mResults.get(position);
}
@Override
public Filter getFilter() {
return new Filter() {
private boolean mHasResults = false;
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// do nothing here because it's executed in another thread and Realm really
// doesn't like treating data from another thread.
final FilterResults results = new FilterResults();
results.count = mHasResults ? 1 : 0; // AutoCompleteTextView already hides dropdown here if count is 0, so correct it.
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// back on the main thread, we can do the query and notify
if (constraint != null) {
mResults = performRealmFiltering(constraint, mRealmObjectList);
mHasResults = mResults.size() > 0;
notifyDataSetChanged();
}
}
};
}
protected abstract List<T> performRealmFiltering(@NonNull CharSequence constraint, RealmResults<T> results);
}
How can I use this to set the adapter in my MainActivity? I guess its done by extending it and overriding the abstract method. But my MainActivity already extends AppCompatActivity and adapter class already extends ArrayAdapter, so I'm confused. All support are appreciated.
回答1:
I kinda rewrote the code above and I think it should work.
public abstract class FilterableRealmBaseAdapter<T extends RealmModel> extends ArrayAdapter<T> implements Filterable {
private RealmResults<T> results;
private final RealmChangeListener realmChangeListener;
public FilterableRealmBaseAdapter(Context context, @LayoutRes int layout, @Nullable RealmResults<T> initialResults) {
super(context, layout);
this.realmChangeListener = new RealmChangeListener() {
@Override
public void onChange(Object element) {
notifyDataSetChanged();
}
};
this.results = initialResults;
if(results != null && results.isValid()) {
results.addChangeListener(realmChangeListener);
}
}
@Override
public int getCount() {
return results == null || !results.isValid() ? 0 : results.size();
}
@Override
public T getItem(int position) {
return results == null || !results.isValid() ? null : results.get(position);
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return new FilterResults();
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (constraint != null) {
if(this.results != null && this.results.isValid()) {
results.removeChangeListeners();
}
this.results = executeRealmQuery(constraint);
results.addChangeListener(realmChangeListener);
notifyDataSetChanged();
}
}
};
}
protected abstract RealmResults<T> executeRealmQuery(@NonNull CharSequence constraint);
}
public class SomethingRealmAdapter extends FilterableRealmBaseAdapter<Something> {
private final Realm realm;
public SomethingRealmAdapter(Context context, @LayoutRes int layout, @Nullable RealmResults<Something> results, Realm realm) {
super(context, layout, results);
this.realm = realm;
}
protected RealmResults<T> executeRealmQuery(@NonNull CharSequence constraint) {
return realm.where(Something.class)
.contains(SomethingFields.NAME, constraint.toString(), Case.INSENSITIVE)
.findAllSorted(SomethingFields.NAME, Sort.ASCENDING);
}
}
来源:https://stackoverflow.com/questions/39179576/android-realm-abstract-class-instantiate