我自己的ArrayAdapter中出现了奇怪的NullPointerException

时间:2018-07-06 20:28:14

标签: java android layout android-arrayadapter

我是Android Studio编程的初学者,现在通过蓝牙制作某种Messenger。所以我有自己的ArrayAdapter类,它扩展了ArrayAdapter类,它用于传出和传入消息。我希望传入的消息位于左侧,传出的消息位于右侧,因此我为此适配器进行了两种布局。我知道,在stackoverflow上,有很多解决方案可以使ArrayAdapter的每一行具有很少的不同布局,但是它们中的每一个都不起作用-更改布局会导致每一行的视图改变。所以我的解决方案是制作另一个ArrayList的布尔值,然后在getView()中检查此列表中包含的内容(是或否),并在ArrayAdapter的那一行上使用正确的布局(我正在通过getView( ))。当我向第二个设备发送大量消息并尝试响应第一个设备时,出现了NullPointerException与 (TextView)row.findViewById(R.id.singleIncomingMessage);

(TextView)row.findViewById(R.id.singleOutgoingMessage);

此异常似乎是随机出现的,但是当然必须有某种模式。这是完整的代码。怎么了如果有一些拼写错误,我为我的语言感到抱歉;)

public class MyArrayAdapter extends ArrayAdapter<String> {
    public MyArrayAdapter(Context context, ArrayList<String> list) {
        super(context, 0, list);
        this.list =list;
        this.context=context;
    }

    ArrayList<String> list;
    Context context;

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public String getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public int getItemViewType(int position) {
        if(Messenger.inOut){
            return 1;
        }
        else{
            return 0;
        }
    }
    @Override
    public int getViewTypeCount() {
        return 2;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        int type=getItemViewType(position);
        View row=convertView;
        if(row==null){
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if(Messenger.inOutList.get(position)==0){
                row=inflater.inflate(R.layout.outgoing_message_layout, parent, false);
            }
            if(Messenger.inOutList.get(position)==1){
                row=inflater.inflate(R.layout.incoming_message_layout, parent, false);
            }
        }
        String message=getItem(position);
        TextView label;
        if(Messenger.inOutList.get(position)==0){
            label=(TextView)row.findViewById(R.id.singleOutgoingMessage);
            label.setText(message);
        }
        if(Messenger.inOutList.get(position)==1){
            label=(TextView)row.findViewById(R.id.singleIncomingMessage);
            label.setText(message);
        }
        return row;
    }
}

2 个答案:

答案 0 :(得分:0)

我认为问题出在row非空的情况下。它可能以前被夸大为外发邮件布局,现在您正在回收它并尝试将其视为外来邮件布局,因此找不到TextView

尽管我真的不知道Messenger.*调用在代码中的行为,但是很难确定这是问题所在。由于您已经在type中获得了getView,因此,如果保持这种方式,则应该使用该视图而不是Messenger.inOutList.get(position)==X来确定使用哪种视图逻辑。 This question对于如何一致地执行此操作有一些很好的答案。

还请记住,要执行此操作,getItemViewType必须始终为给定位置返回相同的类型,否则必须检测到更改并在getView中填充新的布局。如果Messenger.inOut为常数,则没有理由使用此格式(多布局格式)。如果它不是一个常数并且被更改,那么您需要在getView

中进行检测

答案 1 :(得分:0)

好的,非常感谢,我终于做到了。我使用了两个列表(布尔值和消息),在我了解ArrayAdapter之后,我决定使用这两个字段创建类并列出其对象。该错误可能是由于第二个布尔值列表所致。如果有人遇到类似问题,请在下面我的最终代码下面。

public class MyArrayAdapter extends ArrayAdapter<MessageWithType> {
public MyArrayAdapter(Context context, ArrayList<MessageWithType> list) {
    super(context, 0, list);
    this.list =list;
    this.context=context;
}
public static final int TYPE_OUT = 0;
public static final int TYPE_IN = 1;

ArrayList<MessageWithType> list;
Context context;

@Override
public int getCount() {
    return list.size();
}

@Override
public MessageWithType getItem(int position) {
    return list.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}
@Override
public int getItemViewType(int position) {
    if(list.get(position).inOut){
        return 1;
    }
    else{
        return 0;
    }
}
@Override
public int getViewTypeCount() {
    return 2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    MessageWithType item=getItem(position);
    int type=getItemViewType(position);
    View row=convertView;
    ViewHolder viewHolder=null;
    if(row==null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if(type==TYPE_OUT){
            row=inflater.inflate(R.layout.outgoing_message_layout, parent, false);
        }
        if(type==TYPE_IN){
            row=inflater.inflate(R.layout.incoming_message_layout, parent, false);
        }
        TextView label=(TextView)row.findViewById(R.id.singleMessage);
        viewHolder=new ViewHolder(label);
        row.setTag(viewHolder);
    }
    else{
        viewHolder=(ViewHolder)row.getTag();
    }
    viewHolder.textView.setText(item.message);

    return row;
}
public class ViewHolder{
    TextView textView;
    public ViewHolder(TextView textView){
        this.textView=textView;
    }
}

}