【发布时间】:2016-04-25 06:08:37
【问题描述】:
我试图了解如何根据对象上的一些信息轻松地告诉两个不同的视图被膨胀...
我的设置是这样的,但我一直因为这个错误而崩溃:
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 没有正确完成......我怎么说如果 cmets isType 为 0 来显示一个视图而其他任何东西都显示另一个视图?
【问题讨论】:
-
检查 switch 中的条件...如果 getViewType() 返回 1,则返回 myViewHolder。稍后检查 holder 的实例是否为 myViewHolder,如 if(holder instanceOf MyViewHolder) 然后更新视图。
-
添加 case:1 是什么意思,我认为默认会返回它,但我也尝试了 case:1,但它仍然显示错误
-
没关系,在onBindViewHolder()中检查holder实例。
-
您必须根据您在回收视图的
getItemViewType中的条件返回viewType 并使用onCreateViewHolder中的switch case 更改ViewHolder -
@BurhanuddinRashid 我该如何返回 viewType 我认为返回一个数字会触发 onCreateViewHolder 中的不同切换案例
标签: android android-recyclerview android-viewholder