如何在回收站视图中显示多个视图?

时间:2016-04-25 06:08:38

标签: android android-recyclerview android-viewholder

我试着理解如何根据对象的某些信息轻松地告诉两个不同的观点...

我的设置是这样的,但我一直在崩溃这个错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setTypeface(android.graphics.Typeface)' on a null object reference

指向这一行:

myViewHolder.commentUsername.setTypeface(boldTypeface);

这是我的适配器:

public class CommentsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<DatabaseComment> dbCommentsList;
    private DatabaseHelper db;
    private Context context;
    private Typeface typeFace, italicTypeface, boldTypeface;


    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
        public TextView commentUsername, commentUserMsg, commentUserDate, commentUserRemove;
        public ImageView emojiIcon;


        public MyViewHolder(View view) {
            super(view);
            commentUsername = (TextView) view.findViewById(R.id.userAdapterUsername);
            commentUserMsg = (TextView) view.findViewById(R.id.commentUserMsg);
            commentUserDate = (TextView) view.findViewById(R.id.commentUserDate);
            commentUserRemove = (TextView) view.findViewById(R.id.commentUserRemove);
            emojiIcon = (ImageView) view.findViewById(R.id.emojiIcon);
            Log.d(Constants.DEBUG, "IN MY VIEW HOLDER");

            view.setOnClickListener(this);
            commentUserRemove.setOnClickListener(this);

        }

        @Override
        public void onClick(View v) {
            if (mOnEntryClickListener != null) {
                Log.d(Constants.DEBUG, "IN On click");
                mOnEntryClickListener.onEntryClick(v, getAdapterPosition());

            }
        }
    }
    private static OnEntryClickListener mOnEntryClickListener;

    public interface OnEntryClickListener {
        void onEntryClick(View view, int position);
    }

    public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
        mOnEntryClickListener = onEntryClickListener;
    }


    public class MyFeatureViewHolder extends RecyclerView.ViewHolder {
        public TextView commentCompany, commentCompanyMsg, commentCompanyDate;
        public ImageView emojiIcon;


            public MyFeatureViewHolder(View view) {
            super(view);
                commentCompany = (TextView) view.findViewById(R.id.commentCompany);
                commentCompanyMsg = (TextView) view.findViewById(R.id.commentCompanyMsg);
                commentCompanyDate = (TextView) view.findViewById(R.id.commentCompanyDate);
                emojiIcon = (ImageView) view.findViewById(R.id.emojiIcon);
                Log.d(Constants.DEBUG, "IN MY VIEW HOLDER");


        }


    }

    public CommentsAdapter(Context mContext, List<DatabaseComment> comments, Typeface myTypeface, Typeface myTypefaceItalic, Typeface myTypefaceBold) {
        context = mContext;
        db = new DatabaseHelper(context);
        dbCommentsList = comments;
        typeFace = myTypeface;
        italicTypeface = myTypefaceItalic;
        boldTypeface = myTypefaceBold;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case 0:
                return new MyFeatureViewHolder(LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.comment_business_item, parent, false)); 
            case 1:
                return new MyFeatureViewHolder(LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.comment_user_item, parent, false));   
        }
        return new MyViewHolder(LayoutInflater.from(parent.getContext())
                .inflate(R.layout.comment_user_item, parent, false));


    }



    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        //int pos = getItemViewType(position);

        //is a business comment
        if(dbCommentsList.get(position).getIsType() == 0) {


            MyFeatureViewHolder featureViewHolder = (MyFeatureViewHolder) holder;

            DatabaseComment dbComment = dbCommentsList.get(position);

            featureViewHolder.commentCompany.setTypeface(boldTypeface);
            featureViewHolder.commentCompanyMsg.setTypeface(typeFace);
            featureViewHolder.commentCompanyDate.setTypeface(italicTypeface);

            featureViewHolder.commentCompany.setText(dbComment.getUsername());
            featureViewHolder.commentCompanyMsg.setText(dbComment.getCommentText());

            Calendar date = Calendar.getInstance();
            date.setTimeInMillis(dbComment.getCommentDate());
            String commentDateTxt = (date.get(Calendar.MONTH) + "." + date.get(Calendar.DAY_OF_MONTH) + "." + date.get(Calendar.YEAR));

            featureViewHolder.commentCompanyDate.setText(commentDateTxt);


            //anything greater than 0 is a user comment
        } else {
            //TODO show x button near viewHolder if isChanged is 1

            MyViewHolder myViewHolder = (MyViewHolder) holder;

            if(dbCommentsList.get(position).getIsChanged() == 1) {
                myViewHolder.commentUserRemove.setVisibility(View.VISIBLE);
            } else {
                myViewHolder.commentUserRemove.setVisibility(View.GONE);
            }

            DatabaseComment dbComment = dbCommentsList.get(position);

            myViewHolder.commentUsername.setTypeface(boldTypeface);
            myViewHolder.commentUserMsg.setTypeface(typeFace);
            myViewHolder.commentUserDate.setTypeface(italicTypeface);

            myViewHolder.commentUsername.setText(dbComment.getUsername());
            myViewHolder.commentUserMsg.setText(dbComment.getCommentText());

            Calendar date = Calendar.getInstance();
            date.setTimeInMillis(dbComment.getCommentDate());
            String commentDateTxt = (date.get(Calendar.MONTH) + "." + date.get(Calendar.DAY_OF_MONTH) + "." + date.get(Calendar.YEAR));

            myViewHolder.commentUserDate.setText(commentDateTxt);

            int[] commentsImageList = new int[]{R.drawable.ic_announcement_black_18dp, R.drawable.ic_announcement_black_18dp, R.drawable.ic_announcement_black_18dp, R.drawable.ic_explore_black_18dp};
            myViewHolder.emojiIcon.setImageResource(commentsImageList[dbComment.getIsType()]);



        }

        //grab more comments
        if(position > (dbCommentsList.size() - 3) && (dbCommentsList.size() % 20) == 0) {
            grabMoreComments();
        }

    }

    private void grabMoreComments() {
        //TODO
        //GRABAPI - OFFSET dbCommentsList.SIZE - IN LIMIT OF 20
    }



    @Override
    public int getItemCount() {
        return dbCommentsList.size();
    }



    @Override
    public int getItemViewType(int position) {
        if(dbCommentsList.get(position).getIsType() == 0) {
            return 0;
        }
        return 1;
    }
}

这是我设置适配器的类:

private void setupAdapter() {
        commentsAdapter = new CommentsAdapter(this, dbCommentsList, TypeFaceProvider.getTypeFace(this, 0),
                TypeFaceProvider.getTypeFace(this, 1), TypeFaceProvider.getTypeFace(this, 2));
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        commentsRecyclerView.setLayoutManager(mLayoutManager);
        commentsRecyclerView.setItemAnimator(new DefaultItemAnimator());

        //TODO CHECK THAT CLICKING ON COMMENT BY BUSINESS NOTHING HAPPENS

        commentsAdapter.setOnEntryClickListener(new CommentsAdapter.OnEntryClickListener() {
            @Override
            public void onEntryClick(View view, int position) {
                DatabaseComment comment = dbCommentsList.get(position);
                TextView deleteBtn = (TextView) view.findViewById(R.id.commentUserRemove);
                if(view == deleteBtn) {

                    //used to remove the comment from db and the list
                    db.removeSingleComment(comment);
                    dbCommentsList.remove(position);
                    commentsAdapter.notifyDataSetChanged();

                } else {
                    Toast.makeText(getApplicationContext(), comment.getUsername() + " is selected!", Toast.LENGTH_SHORT).show();
                    takeToUserProfile(dbCommentsList.get(position));
                }
            }
        });




        commentsRecyclerView.setAdapter(commentsAdapter);

        commentsAdapter.notifyDataSetChanged();

    }

所以在适配器中getItemViewType没有正确完成...如果注释isType为0表示一个视图而其他任何东西显示另一个视图怎么说?

2 个答案:

答案 0 :(得分:3)

首先,您需要覆盖适配器的getItemViewType,如下所示:(我假设您可以将viewholders与对象的getType()方法匹配。)

@Override
   public int getItemViewType(int position) {
      return items.get(position).getType();
   }

在您的onCreateViewHolder方法切换类型中,返回相关的视图。

     @Override
       public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          View view = null;
          switch (viewType) {
              case ITEM_TYPE_A:
                  view = mInflater.inflate(R.layout.your_row_a, parent, false);
                  return new ATypeViewHolder(view);

              case ITEM_TYPE_B:
                  view = mInflater.inflate(R.layout.your_row_b, parent, false);
                  return new BTypeViewHolder(view);
    }
}

使用适配器的onBindViewHolder方法。

@Override
   public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
         Item item = items.get(position);
         if(item != null){
              initializeViews(item, holder, position);
         }
}

最后,在您的initializeViews方法中,根据您的项目类型投射您的观看者并使用它:

private void initializeViews(final Item item, final RecyclerView.ViewHolder viewHolder, final int position) {
     swtich(item.gettype())
     {
        case ITEM_TYPE_A:
            ATypeViewHolder holder = (ATYpeViewHolder)viewHolder;
            // init your views

        case ITEM_TYPE_B:
            BTypeViewHolder holder = (BTypeViewHolder)viewHolder;
            // init your views.
     }
}

不是:您的观看者必须扩展RecyclerView.ViewHolder

我希望这对你有帮助。祝你好运。

答案 1 :(得分:1)

根据错误,它看起来像布局文件中缺少id为R.id.userAdapterUsername的视图comment_user_item.xml