【问题标题】:CursorRecyclerViewAdapter with Multiple Viewtypes具有多种视图类型的 CursorRecyclerViewAdapter
【发布时间】:2015-09-19 06:15:13
【问题描述】:

我正在使用来自 this code snippet 的 CursorRecyclerViewAdapter

当我在 recyclerview 中使用 Single Viewtype 时效果很好。但是如果我使用多个 viewtypes 我会崩溃说int android.support.v7.widget.RecyclerView$ViewHolder.mItemViewType null object reference

我使用下面的代码来扩展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);
    }
}}

【问题讨论】:

  • 您在哪里分配视图类型(我的意思是视图的类型为 VIEW_HOLDER_TYPE_1 或 VIEW_HOLDER_TYPE_2)???
  • @pskink inside on onBindViewHolder 我设置了 viewtype if (postitem.isFromMe()==true){ viewtype=1; } else { viewtype=2; }
  • 请阅读public int RecyclerView.Adapter#getItemViewType(int position)的文档

标签: android android-cursoradapter android-recyclerview


【解决方案1】:

我是这样解决的

创建一个私有游标并分配它

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

}

实现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;

}

更改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;
    }
}

【讨论】:

  • 您的getItemViewType() 似乎不正确。最后的return 1 没有意义,它应该被真正的后备所取代,更不用说VIEW_HOLDER_TYPE_1VIEW_HOLDER_TYPE_2 const 也很有可能等于1。因此,您应该回退到具有明确含义的内容,例如具有独特价值的 VIEW_HOLDER_TYPE_NONE
【解决方案2】:

问题(我认为)是 RecyclerView 不知道您有多个视图类型。

解决方案可能是覆盖getItemViewType。但是,当您只能从 Cursor 中决定 viewType 时,这可能会很棘手。如果是这种情况,我建议您在 CursorRecyclerViewAdapter 类中覆盖 GetItemViewType 方法。

@Override
public int getItemViewType(int position){
    int viewType = cursor // somehow determine the viewType;
    return viewType;
}

【讨论】:

    【解决方案3】:

    您应该实现getItemViewType 来为回收站视图中的每个位置返回正确的 ViewType。见教程here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      相关资源
      最近更新 更多