我无法弄清楚为什么我使用不同行类型的自定义NullPointerException
获得BaseAdapter
。我正在使用ViewHolder
模式,当我得到这个NPE时,ViewHolder为空。但是查看下面的代码,是不是总会引用ViewHolder?
使用getItemViewType
应始终返回有效的行布局,并在第一个switch
语句中覆盖所有这些类型,以处理行的膨胀。
这一行是给我问题的问题:
case TYPE_TEXT_YOU:
if (message != null) holder.message.setText(message);
这很奇怪,因为之前工作正常。我没有太大变化,但现在它给了我这个问题。请帮忙!!!
public class ChatAdapter extends BaseAdapter {
private static final int TYPE_TEXT_YOU = 0;
private static final int TYPE_AUDIO_YOU = 1;
private static final int TYPE_TEXT_THEM = 2;
private static final int TYPE_AUDIO_THEM = 3;
private static final int TYPE_MATCH_NOTICE = 4;
private static final int TYPE_EMPTY_ROW = 5;
private Context mContext;
private List<ChatMessage> mMessages;
private String mPartnerUserId;
private SharedPrefs mPrefs;
private DatabaseHelper mDb;
private User mUser;
private User mPartnerUser;
private AudioHelper mAudioHelper;
public ChatAdapter(Context context, List<ChatMessage> messages, String partnerUserId) {
mContext = context;
mMessages = messages;
mPartnerUserId = partnerUserId;
mPrefs = new SharedPrefs(context);
mAudioHelper = AudioHelper.getInstance(context, partnerUserId);
mDb = DatabaseHelper.getInstance(context);
mUser = mDb.getUser(mPrefs.getUserId());
mPartnerUser = mDb.getUser(partnerUserId);
}
@Override
public int getCount() {
return mMessages.size();
}
@Override
public Object getItem(int position) {
return mMessages.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
ChatMessage message = mMessages.get(position);
switch (message.getMessageType()) {
case ChatMessage.TYPE_GAME_DATE:
return TYPE_MATCH_NOTICE;
case ChatMessage.TYPE_TEXT:
if (message.getSenderUserId().equals(mPrefs.getUserId())) {
return TYPE_TEXT_YOU;
}
else {
return TYPE_TEXT_THEM;
}
case ChatMessage.TYPE_AUDIO:
if (message.getSenderUserId().equals(mPrefs.getUserId())) {
return TYPE_AUDIO_YOU;
}
else {
return TYPE_AUDIO_THEM;
}
default:
return TYPE_EMPTY_ROW;
}
}
@Override
public int getViewTypeCount() {
return 6;
}
public class ViewHolder {
private ImageView avatar;
private CustomTextView timestamp;
private CustomTextView message;
private CustomTextView date;
private CustomTextView time;
private LinearLayout btnPlayAudio;
private ImageView ivPlayAudio;
private ProgressBar spinPlayingAudio;
private CustomTextView tvPlayAudio;
private ImageView gameCover;
private ProgressBar spinGameCover;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context
.LAYOUT_INFLATER_SERVICE);
switch (type) {
case TYPE_TEXT_YOU:
convertView = inflater.inflate(R.layout.row_chat_you, parent, false);
holder.avatar = (ImageView) convertView.findViewById(R.id.avatar_you);
holder.message = (CustomTextView) convertView.findViewById(R.id.message_you);
holder.timestamp = (CustomTextView) convertView.findViewById(R.id.timestamp_you);
break;
case TYPE_AUDIO_YOU:
convertView = inflater.inflate(R.layout.row_chat_audio_you, parent, false);
holder.avatar = (ImageView) convertView.findViewById(R.id.avatar_you);
holder.timestamp = (CustomTextView) convertView.findViewById(R.id.timestamp_you);
holder.btnPlayAudio = (LinearLayout) convertView.findViewById(R.id.btn_play_audio_you);
holder.ivPlayAudio = (ImageView) convertView.findViewById(R.id.iv_play_audio);
holder.spinPlayingAudio = (ProgressBar) convertView.findViewById(R.id.spin_playing_audio);
holder.tvPlayAudio = (CustomTextView) convertView.findViewById(R.id.tv_play_audio);
break;
case TYPE_TEXT_THEM:
convertView = inflater.inflate(R.layout.row_chat_them, parent, false);
holder.avatar = (ImageView) convertView.findViewById(R.id.avatar_them);
holder.message = (CustomTextView) convertView.findViewById(R.id.message_them);
holder.timestamp = (CustomTextView) convertView.findViewById(R.id.timestamp_them);
break;
case TYPE_AUDIO_THEM:
convertView = inflater.inflate(R.layout.row_chat_audio_them, parent, false);
holder.avatar = (ImageView) convertView.findViewById(R.id.avatar_them);
holder.timestamp = (CustomTextView) convertView.findViewById(R.id.timestamp_them);
holder.btnPlayAudio = (LinearLayout) convertView.findViewById(R.id.btn_play_audio_them);
holder.ivPlayAudio = (ImageView) convertView.findViewById(R.id.iv_play_audio);
holder.spinPlayingAudio = (ProgressBar) convertView.findViewById(R.id.spin_playing_audio);
holder.tvPlayAudio = (CustomTextView) convertView.findViewById(R.id.tv_play_audio);
break;
case TYPE_MATCH_NOTICE:
convertView = inflater.inflate(R.layout.row_chat_match_notice, parent, false);
holder.gameCover = (ImageView) convertView.findViewById(R.id.game_cover);
holder.spinGameCover = (ProgressBar) convertView.findViewById(R.id.spin_game_cover);
holder.date = (CustomTextView) convertView.findViewById(R.id.date);
holder.time = (CustomTextView) convertView.findViewById(R.id.time);
break;
case TYPE_EMPTY_ROW:
convertView = inflater.inflate(R.layout.row_padding_10dp, parent, false);
break;
}
convertView.setTag(holder);
}
else holder = (ViewHolder) convertView.getTag();
String message = mMessages.get(position).getMessage();
String timestamp = mMessages.get(position).getTimeStamp();
final String audioFilepath = mMessages.get(position).getFilepath();
DateTime dateTime;
DateTimeFormatter formatter = DateTimeFormat.forPattern(GlobalVars.FORMAT_MESSAGE_TIMESTAMP);
final ViewHolder finalHolder = holder;
switch (type) {
case TYPE_TEXT_YOU:
if (message != null) holder.message.setText(message);
if (timestamp != null && !timestamp.isEmpty()) {
try {
dateTime = ISODateTimeFormat.dateTime().parseDateTime(timestamp);
if (dateTime != null) holder.timestamp.setText(formatter.print(dateTime));
}
catch (IllegalArgumentException e) { e.printStackTrace(); }
}
if (mUser != null && mUser.getAvatarType() != null && !mUser.getAvatarType().isEmpty()) {
try {
holder.avatar.setImageDrawable(mContext.getResources().getDrawable(ViewHelper
.getAvatarHeadDrawableId(mContext, mUser.getAvatarType())));
}
catch (Resources.NotFoundException e) { e.printStackTrace(); }
}
break;
case TYPE_AUDIO_YOU:
if (timestamp != null && !timestamp.isEmpty()) {
try {
dateTime = ISODateTimeFormat.dateTime().parseDateTime(timestamp);
if (dateTime != null) holder.timestamp.setText(formatter.print(dateTime));
}
catch (IllegalArgumentException e) { e.printStackTrace(); }
}
if (mUser != null && mUser.getAvatarType() != null && !mUser.getAvatarType().isEmpty()) {
try {
holder.avatar.setImageDrawable(mContext.getResources().getDrawable(ViewHelper
.getAvatarHeadDrawableId(mContext, mUser.getAvatarType())));
}
catch (Resources.NotFoundException e) { e.printStackTrace(); }
}
holder.btnPlayAudio.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (audioFilepath != null && !audioFilepath.isEmpty()) {
mAudioHelper.changeViewsOfStoppedAudioMessage();
mAudioHelper.setPlayingAudioViews(finalHolder.ivPlayAudio,
finalHolder.spinPlayingAudio, finalHolder.tvPlayAudio);
mAudioHelper.playAudio(audioFilepath);
}
}
});
break;
case TYPE_TEXT_THEM:
if (message != null) holder.message.setText(message);
if (timestamp != null && !timestamp.isEmpty()) {
try {
dateTime = ISODateTimeFormat.dateTime().parseDateTime(timestamp);
if (dateTime != null) holder.timestamp.setText(formatter.print(dateTime));
}
catch (IllegalArgumentException e) { e.printStackTrace(); }
}
if (mPartnerUser != null && mPartnerUser.getAvatarType() != null) {
try {
holder.avatar.setImageDrawable(mContext.getResources().getDrawable(ViewHelper
.getAvatarHeadDrawableId(mContext, mPartnerUser.getAvatarType())));
}
catch (Resources.NotFoundException e) { e.printStackTrace(); }
}
break;
case TYPE_AUDIO_THEM:
if (timestamp != null && !timestamp.isEmpty()) {
try {
dateTime = ISODateTimeFormat.dateTime().parseDateTime(timestamp);
if (dateTime != null) holder.timestamp.setText(formatter.print(dateTime));
}
catch (IllegalArgumentException e) { e.printStackTrace(); }
}
if (mPartnerUser != null && mPartnerUser.getAvatarType() != null) {
try {
holder.avatar.setImageDrawable(mContext.getResources().getDrawable(ViewHelper
.getAvatarHeadDrawableId(mContext, mPartnerUser.getAvatarType())));
}
catch (Resources.NotFoundException e) { e.printStackTrace(); }
}
holder.btnPlayAudio.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (audioFilepath != null && !audioFilepath.isEmpty()) {
mAudioHelper.changeViewsOfStoppedAudioMessage();
mAudioHelper.setPlayingAudioViews(finalHolder.ivPlayAudio,
finalHolder.spinPlayingAudio, finalHolder.tvPlayAudio);
mAudioHelper.playAudio(audioFilepath);
}
}
});
break;
case TYPE_MATCH_NOTICE:
if (message != null) {
if (message.contains("{")) {
Bundle info = null;
message = message.substring(message.indexOf("{"));
try {
JSONObject obj = new JSONObject(message);
info = JsonHelper.parseMatchNoticeMessageJson(obj);
}
catch (JSONException e) { e.printStackTrace(); }
if (info != null) {
if (info.containsKey(GlobalVars.KEY_GAME) && info.containsKey(GlobalVars
.KEY_PLATFORM)) {
Game game = mDb.getGame(info.getString(GlobalVars.KEY_GAME),
info.getString(GlobalVars.KEY_PLATFORM));
if (game != null && game.getCoverPhoto() != null) {
ViewHelper.loadOrDownloadGameCover(mContext, game.getCoverPhoto(),
holder.gameCover, holder.spinGameCover);
}
}
if (info.containsKey(GlobalVars.KEY_GAME_TIME)) {
String matchTime = info.getString(GlobalVars.KEY_GAME_TIME);
if (matchTime != null && !matchTime.isEmpty()) {
try {
dateTime = ISODateTimeFormat.dateTime().parseDateTime(matchTime);
if (dateTime != null) {
holder.date.setText(DateTimeFormat.forPattern(GlobalVars
.FORMAT_DATE_WITH_DAY_OF_WEEK).print(dateTime));
holder.time.setText(DateTimeFormat.forPattern(GlobalVars
.FORMAT_TIME).print(dateTime));
}
}
catch (IllegalArgumentException e) { e.printStackTrace(); }
}
}
}
}
}
break;
}
return convertView;
}
public void refreshList(List<ChatMessage> updatedMessages) {
mMessages.clear();
mMessages.addAll(updatedMessages);
this.notifyDataSetChanged();
}
}
我的Stacktrace
java.lang.NullPointerException
at com.walintukai.lovelup.adapters.ChatAdapter$ViewHolder.access$100(ChatAdapter.java:118)
at com.walintukai.lovelup.adapters.ChatAdapter.getView(ChatAdapter.java:201)
at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:230)
at android.widget.AbsListView.obtainView(AbsListView.java:2739)
at android.widget.ListView.makeAndAddView(ListView.java:1801)
at android.widget.ListView.fillUp(ListView.java:733)
at android.widget.ListView.fillGap(ListView.java:670)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:6747)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3988)
at android.widget.AbsListView.onTouchMove(AbsListView.java:4840)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:4668)
at android.view.View.dispatchTouchEvent(View.java:8135)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2417)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2141)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2423)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2156)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2295)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1622)
at android.app.Activity.dispatchTouchEvent(Activity.java:2565)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2243)
at android.view.View.dispatchPointerEvent(View.java:8343)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4743)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4609)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4167)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4221)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4190)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4301)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4198)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4358)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4167)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4221)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4190)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4198)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4167)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6517)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6434)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6405)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6370)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6597)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
at android.os.MessageQueue.next(MessageQueue.java:138)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:5579)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(NativeStart.java)
答案 0 :(得分:0)
玩了一遍,找到了答案。所以我猜这些行的一些标记是null
所以它会调用带有else
的{{1}}语句convertView.getTag()
。
解决方案是检查null
是否如此:
convertView.getTag() == null