Search code examples
androidandroid-cursoradapterandroid-recyclerview

CursorRecyclerViewAdapter with Multiple Viewtypes


I'm using CursorRecyclerViewAdapter from this code snippet

It works fine When I use Single Viewtype in recyclerview.But If i use multiple viewtypes I get crashes saying int android.support.v7.widget.RecyclerView$ViewHolder.mItemViewType null object reference

I use the below code to extend CursorRecyclerViewAdapter

public class PostCursorAdapter extends CursorRecyclerViewAdapter<RecyclerView.ViewHolder> {

private static final int VIEW_HOLDER_TYPE_1=1;
private static final int VIEW_HOLDER_TYPE_2=2;
private Integer viewtype=0;

public PostCursorAdapter(Context context,Cursor cursor){
    super(context,cursor);

}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, Cursor cursor) {
    PostItem postitem = PostItem.fromCursor(cursor);
    Log.d("PostItem",postitem.toString());
        int viewtype=1;

    if (postitem.isFromMe()==true){
       viewtype=1;
      }
     else {
       viewtype=2;
      }

    switch (viewtype) {

        case VIEW_HOLDER_TYPE_1:
            ViewHolder_Type1 viewholder1 = (ViewHolder_Type1) holder;
            TextView mytimeView = (TextView) viewholder1.mytimeTextView;
            mytimeView.setText(postitem.getPostTime());
            TextView mymsgView = (TextView) viewholder1.mymessageTextView;
            mymsgView.setText(postitem.getPostMsg());
            break;

        case VIEW_HOLDER_TYPE_2:
            ViewHolder_Type2 viewholder2 = (ViewHolder_Type2) holder;
            TextView timeView = (TextView) viewholder2.timeTextView;
            timeView.setText(postitem.getPostTime());
            TextView msgView = (TextView) viewholder2.messageTextView;
            msgView.setText(postitem.getPostMsg());
            break;

        default:
            break;
    }
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v;

    switch (viewType) {

        case VIEW_HOLDER_TYPE_1:
            v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.mypost, parent, false);
            ViewHolder_Type1 vh1 = new ViewHolder_Type1(v);
            return vh1;

        case VIEW_HOLDER_TYPE_2:
            v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.post, parent, false);
            ViewHolder_Type2 vh2 = new ViewHolder_Type2(v);
            return vh2;

        default:
            break;
    }

    return null;
}
public static class ViewHolder_Type1 extends RecyclerView.ViewHolder {
    public TextView mymessageTextView, mytimeTextView;
    public ViewHolder_Type1(View v) {
        super(v);
        this.mymessageTextView = (TextView) v.findViewById(R.id.mymessageTextView);
        this.mytimeTextView = (TextView) v.findViewById(R.id.mytimeTextView);
    }


}

public static class ViewHolder_Type2 extends RecyclerView.ViewHolder {
    public TextView messageTextView, timeTextView;
    public ViewHolder_Type2(View v) {
        super(v);
        this.messageTextView = (TextView) v.findViewById(R.id.messageTextView);
        this.timeTextView = (TextView) v.findViewById(R.id.timeTextView);
    }
}}

Solution

  • Here is how I solved it

    create a private Cursor and assign it

        public PostCursorAdapter(Context context,Cursor cursor){
        super(context,cursor);
        mCursor=cursor;
    
    }
    

    Implement getItemViewType

     @Override
    public int getItemViewType(int position) {
            if (mCursor.moveToPosition(position))
            {
                PostItem postItem=PostItem.fromCursor(mCursor);
                if (postItem.isFromMe())
                {
                    return VIEW_HOLDER_TYPE_1;
    
                }
                else
                {
                    return VIEW_HOLDER_TYPE_2;
    
                }
            }
        return 1;
    
    }
    

    Change onBindViewHolder

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, Cursor cursor) {
        PostItem postitem = PostItem.fromCursor(cursor);
    
        switch (getItemViewType(cursor.getPosition())) {
    
            case VIEW_HOLDER_TYPE_1:
                ViewHolder_Type1 viewholder1 = (ViewHolder_Type1) holder;
                TextView mytimeView = (TextView) viewholder1.mytimeTextView;
                mytimeView.setText(postitem.getPostTime());
                TextView mymsgView = (TextView) viewholder1.mymessageTextView;
                mymsgView.setText(postitem.getPostMsg());
                break;
    
            case VIEW_HOLDER_TYPE_2:
                ViewHolder_Type2 viewholder2 = (ViewHolder_Type2) holder;
                TextView timeView = (TextView) viewholder2.timeTextView;
                timeView.setText(postitem.getPostTime());
                TextView msgView = (TextView) viewholder2.messageTextView;
                msgView.setText(postitem.getPostMsg());
                break;
    
            default:
                break;
        }
    }