如何在回收站视图中显示多个查看器?
How to show multiple viewholders in recycler view?
我试图了解如何根据对象的一些信息轻松地告诉两个不同的视图被夸大...
我的设置是这样的,但我总是因为这个错误而崩溃:
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;
}
}
这是我设置适配器的 class:
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 以显示一个视图而其他任何内容显示另一个视图,我该怎么说?
首先,您需要像下面这样重写适配器的 getItemViewType
:(我假设您可以将 viewholders
与对象的 getType()
方法相匹配。)
@Override
public int getItemViewType(int position) {
return items.get(position).getType();
}
并在您的 onCreateViewHolder
方法中切换类型和 return 您的相关视图。
@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
方法中根据你的项目类型转换你的 viewholder 并使用它:
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
希望对您有所帮助。祝你好运。
根据错误,布局文件中似乎缺少 ID 为 R.id.userAdapterUsername 的视图 comment_user_item.xml
我试图了解如何根据对象的一些信息轻松地告诉两个不同的视图被夸大...
我的设置是这样的,但我总是因为这个错误而崩溃:
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;
}
}
这是我设置适配器的 class:
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 以显示一个视图而其他任何内容显示另一个视图,我该怎么说?
首先,您需要像下面这样重写适配器的 getItemViewType
:(我假设您可以将 viewholders
与对象的 getType()
方法相匹配。)
@Override
public int getItemViewType(int position) {
return items.get(position).getType();
}
并在您的 onCreateViewHolder
方法中切换类型和 return 您的相关视图。
@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
方法中根据你的项目类型转换你的 viewholder 并使用它:
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
希望对您有所帮助。祝你好运。
根据错误,布局文件中似乎缺少 ID 为 R.id.userAdapterUsername 的视图 comment_user_item.xml