RealmBaseAdapter with multiple RealmObjects

2020-07-30 00:11发布

问题:

I created two RealmObjects:

public class HashtagObject extends RealmObject

public class SearchtagObject extends RealmObject

Then I want to use one adapter for two RealmObjects, I try to add RealmBaseAdapter with generic but it's not correct:

public  class CustomListAdapter extends RealmBaseAdapter<T extends RealmObject> implements ListAdapter{

private final OrderedRealmCollection<T>  mItenName;
private Activity mContext;

public CustomListAdapter(Activity context, OrderedRealmCollection<T> realmResults){
    super(context, realmResults);
    this.mItenName=realmResults;
    this.mContext= context;
}}

How do I use one adapter with multiple RealmObjects?

回答1:

Your problem is that you shouldn't create two RealmObjects for this task. You should create one RealmObject.

public class HashtagObject extends RealmObject

public class SearchtagObject extends RealmObject

These should be

public class TagObject extends RealmObject {
    @Index
    private String type; //HASHTAG or SEARCHTAG

If you still need to show them separately, then you'll need two results, in which case you'll definitely need your custom adapter.

For this, I'd recommend somewhat mirroring what RealmRecyclerViewAdapter does.

public class SearchAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    RealmResults<HashtagObject> hashtags;
    RealmResults<SearchtagObject> searchtags;

    Realm realm;

    RealmChangeListener realmChangeListener = new RealmChangeListener() {
        @Override
        public void onChange(Object element) {
            notifyDataSetChanged();
        }
    }

    public SearchAdapter(Realm realm) {
        this.hashtags = realm.where(HashTagObject.class).findAllAsync();
        this.searchtags = realm.where(SearchtagObject.class).findAllAsync();

        this.hashtags.addChangeListener(realmChangeListener);
        this.searchtags.addChangeListener(realmChangeListener);
    }

    private <T extends RealmModel> int getResultSize(RealmResults<T> results) {
        return ((results == null) || (!results.isValid()) || (results.isValid() && !results.isLoaded()) ? 0 : results.size();
    }

    @Override
    public int getItemCount() {
        return 1 /* header */ + getResultSize(hashtags) + 1 /* header */ + getResultSize(searchtags);
    }

    static final int HEADER = 0;
    static final int HASH = 1;
    static final int SEARCH = 2;

    @Override
    public int getItemViewType(int position) {
        if(position == 0 || position == 1 /*header*/ + getResultSize(hashtags)) {
            return HEADER;
        }
        if(position < 1 /*header*/ + getResultSize(hashtags)) {
            return HASH;
        }
        return SEARCH;
    }

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType == HEADER) {
            return new HeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.search_header, parent, false));
        }
        if(viewType == HASH) {
            return new HashtagViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.search_hash, parent, false));
        }
        if(viewType == SEARCH) {
            return new SearchViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.search_search, parent, false));
        }
        throw new IllegalArgumentException("Invalid view type [" + viewType + "]");
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder abstractHolder, int position) {
        if(abstractHolder instanceof HeaderViewHolder) {
            HeaderViewHolder holder = (HeaderViewHolder) abstractHolder;
            if(position == 0) {
                holder.setText(R.string.hash_header_text);
            } else {
                holder.setText(R.string.search_header_text);
            }
        } else if(abstractHolder instanceof HashtagViewHolder) {
            HashtagViewHolder holder = (HashtagViewHolder) abstractHolder;
            HashtagObject hashObject = hashtags.get(position - 1 /*header*/);
            holder.bind(hashObject);
        } else if(abstractHolder instanceof SearchViewHolder) {
            SearchViewHolder holder = (SearchViewHolder)abstractHolder;
            SearchtagObject searchObject = searchTags.get(
                 position - 1 /* header */ 
                          - 1 /* other header */ 
                          - getResultSize(hashtags) /* previous list */);
            holder.bind(searchObject);
        }
    }
}