我試圖模擬一個簡單的聊天視圖,使用兩個佈局,一個用於發送,另一個用於接收消息。當我嘗試滾動時,引發NullPointerException。不知道爲什麼會發生。有人可以找到問題。android-NullPointerException在使用自定義適配器在列表視圖中滾動時
public class DisplayMessageAdapter extends ArrayAdapter<Message> {
Context context;
int sentResource, rcvdResource;
ArrayList<Message> messages = null;
public DisplayMessageAdapter(Context context, int sentResource, int rcvdResource, ArrayList<Message> messages) {
super(context, sentResource, rcvdResource, messages);
this.context = context;
this.sentResource = sentResource;
this.rcvdResource = rcvdResource;
this.messages = messages;
}
@SuppressLint("NewApi")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
MessagesHolder holder = null;
Message message = messages.get(position);
if(message.sent != null)
{
if(row == null)
{
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(sentResource, parent, false);
holder = new MessagesHolder();
holder.sent = (TextView) row.findViewById(R.id.sent_message);
row.setTag(holder);
}
else
{
//Log.i("holder-not-null","holder-not-null");
holder = (MessagesHolder) row.getTag();
}
holder.sent.setText(message.sent);
}
else
{
if(row == null)
{
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(rcvdResource, parent, false);
holder = new MessagesHolder();
holder.received = (TextView) row.findViewById(R.id.received_message);
row.setTag(holder);
}
else
{
//Log.i("holder-not-null","holder-not-null");
holder = (MessagesHolder) row.getTag();
}
holder.received.setText(message.received);
}
return row;
}
static class MessagesHolder
{
TextView sent;
TextView received;
} }
sent_message和received_message佈局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/sent_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:textColor="#000000"
android:background="@drawable/sent"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:textSize="15sp"
/>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_alignParentRight="true"
android:id="@+id/received_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/rcvd"
android:layout_marginRight="20dp"
android:textColor="#000000"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:textSize="15sp"
/>
</RelativeLayout>
logcat中調用該適配器
public void populateView(ArrayList<Message> allMessages)
{
DisplayMessageAdapter adapter = new DisplayMessageAdapter(getApplicationContext() , R.layout.sent_message_layout, R.layout.received_message_layout, allMessages);
listview = (ListView) findViewById(R.id.messageview);
listview.setAdapter(adapter);
listview.setSelection(listview.getAdapter().getCount()-1);
}
變化
後12-23 13:46:04.996: E/AndroidRuntime(8131): FATAL EXCEPTION: main
12-23 13:46:04.996: E/AndroidRuntime(8131): java.lang.NullPointerException
12-23 13:46:04.996: E/AndroidRuntime(8131): at com.example.swipetext.DisplayMessageAdapter.getView(DisplayMessageAdapter.java:58)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.widget.AbsListView.obtainView(AbsListView.java:2608)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.widget.ListView.makeAndAddView(ListView.java:1852)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.widget.ListView.fillUp(ListView.java:718)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.widget.ListView.fillGap(ListView.java:655)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:6592)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3706)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.widget.AbsListView.onTouchEvent(AbsListView.java:4556)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.View.dispatchTouchEvent(View.java:7817)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2435)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2159)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2441)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2174)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2441)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2174)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2441)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2174)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2441)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2174)
12-23 13:46:04.996: E/AndroidRuntime(8131): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2326)
12-23 13:46:04.996: E/AndroidRuntime(8131): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1612)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.app.Activity.dispatchTouchEvent(Activity.java:2494)
12-23 13:46:04.996: E/AndroidRuntime(8131): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2274)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.View.dispatchPointerEvent(View.java:8025)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4659)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4547)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4148)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4198)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4167)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4252)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4175)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4309)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4148)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4198)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4167)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4175)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4148)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6293)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6231)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6202)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6373)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:188)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:177)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6346)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6392)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.Choreographer.doCallbacks(Choreographer.java:591)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.Choreographer.doFrame(Choreographer.java:559)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.os.Handler.handleCallback(Handler.java:730)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.os.Handler.dispatchMessage(Handler.java:92)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.os.Looper.loop(Looper.java:137)
12-23 13:46:04.996: E/AndroidRuntime(8131): at android.app.ActivityThread.main(ActivityThread.java:5419)
12-23 13:46:04.996: E/AndroidRuntime(8131): at java.lang.reflect.M
代碼
public class DisplayMessageAdapter extends ArrayAdapter<Message> {
Context context;
int sentResource, rcvdResource;
ArrayList<Message> messages = null;
public DisplayMessageAdapter(Context context, int sentResource, int rcvdResource, ArrayList<Message> messages) {
super(context, sentResource, rcvdResource, messages);
this.context = context;
this.sentResource = sentResource;
this.rcvdResource = rcvdResource;
this.messages = messages;
}
@SuppressLint("NewApi")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
MessagesHolder holder = null;
Message message = messages.get(position);
if(message.sent != null)
{
if(row == null)
{
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(sentResource, parent, false);
holder = new MessagesHolder();
holder.data = (TextView) row.findViewById(R.id.sent_message);
row.setTag(holder);
}
else
{
//Log.i("holder-not-null","holder-not-null");
holder = (MessagesHolder) row.getTag();
}
holder.data.setText(message.sent);
}
else
{
if(row == null)
{
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(rcvdResource, parent, false);
holder = new MessagesHolder();
holder.data = (TextView) row.findViewById(R.id.received_message);
row.setTag(holder);
}
else
{
//Log.i("holder-not-null","holder-not-null");
holder = (MessagesHolder) row.getTag();
}
holder.data.setText(message.received);
}
return row;
}
static class MessagesHolder
{
TextView data;
}
}
發表您的logcat」 – Dhananjay
http://stackoverflow.com/questions/18868194/android-xml-layout-for-a-listview-with-different-items。我想你正在尋找類似的東西 – Raghunandan
你如何區分黑白的發送和接收消息? – Raghunandan