Android Realm Abstract Class Instantiate

2019-09-10 06:18发布

问题:

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