如何在回收视图中显示多个视图?
我试图理解我怎么能轻易分辨两种不同的看法取决于物体上的一些信息进行充气...如何在回收视图中显示多个视图?
我的设置是像这样,但我一直有这个错误而崩溃:
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,显示一个视图和其他任何节目另一种观点?
基于错误看起来与ID R.id.userAdapterUsername在布局文件comment_user_item.xml
我使用了错误的ID忘记了改变它,没有意识到,谢谢! – Lion789
首先,你需要重写你的适配器的getItemViewType
象下面这样:(我假设你可以匹配你的viewholders
与对象的getType()
方法。)
@Override
public int getItemViewType(int position) {
return items.get(position).getType();
}
而在你onCreateViewHolder
法切换类型,并返回你的相关viewholder 。
@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);
}
}
Inıt您的适配器的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.
}
}
不是:您viewholders必须扩展RecyclerView.ViewHolder
我希望这会帮助你的。祝你好运。
哦,我很抱歉,这是我的私人自定义方法。你应该在onBindViewHolder方法中调用它。我编辑了我的帖子。 – savepopulation
我看到你有的方法,但是这并不改变我在我自己的代码中做的事情,你只是在onBindViewHolder之外添加了另一个方法,我已经在其中做了它? – Lion789
此外,该项目上的isType可以是0或大于0 ...因此,这就是为什么我必须查看它是否为0如果不返回1(因为isType可以是0,1,2,3,4等...)但大于0应该夸大不同的看法。 – Lion789
缺少检查条件的开关...返回myViewHolder如果getViewType()返回1的视图。稍后检查持有者的实例是myViewHolder还是不喜欢if(持有者instanceOf MyViewHolder)然后更新视图。 –
你是什么意思加入案件:1,我认为默认会返回它,我试过的情况下:1虽然以及它仍然显示错误 – Lion789
这很好,检查持有人在onBindViewHolder()实例。 –