我希望从JSON内容创建一个列表。这是我的适配器代码:
public class AnswersAdapter extends ArrayAdapter<Answer> {
static Context context;
static int layoutResourceId;
Answer data[] = null;
public AnswersAdapter(Context context, int layoutResourceId, Answer[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
AnswerHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new AnswerHolder();
holder.txtTitle = (TextView)row.findViewById(R.id.answerText);
holder.txtTitle2 = (TextView)row.findViewById(R.id.answerAuthor);
holder.txtTitle3 = (TextView)row.findViewById(R.id.answerVotes);
row.setTag(holder);
}
else
{
holder = (AnswerHolder)row.getTag();
}
Answer hold = data[position];
holder.txtTitle.setText(Html.fromHtml(hold.text));
holder.txtTitle2.setText(hold.author);
holder.txtTitle3.setText(hold.votes);
return row;
}
static class AnswerHolder
{
TextView txtTitle;
TextView txtTitle2;
TextView txtTitle3;
}
}
我正面临这个错误:
java.lang.NullPointerException:尝试从空对象引用上的字段'java.lang.String com.example.shivam.stackoverflow.Answer.text'中读取
在这一行
holder.txtTitle.setText(Html.fromHtml(hold.text));
答案 0 :(得分:1)
您的data
数组包含空值。这是NPE的直接原因,因为对于某些职位,hold
最终为null
。如果你测试它,你将避免使用NPE,但是(正如你在评论中指出的那样)你的适配器将不会正常运行。您不能简单地忽略具有null
数据值的行。
顺便说一句,您应该删除data
成员字段。数组引用已由ArrayAdapter
超类保存。只要您使用getItem(position)
,就可以使用data[position]
。虽然这不会解决NPE问题,但它会简化一些事情,如下所示。
您有几种选择:
data
的某些条目开始为null
的原因并消除根本问题。但是,data
有null
个条目可能是正常的(在适配器的上下文之外)。getView
方法,将holder
中的视图设置为某些指示“数据缺失”的特定值 - 可能是空白,也许是“无数据”消息。 (换句话说,不要简单地跳过所有处理。这就是导致空行和重复行组合的原因。)修改构造函数以消除null
中的data
条目。这将导致更短的列表。一些代码可能是:
public AnswersAdapter(Context context, int layoutResourceId, Answer[] data) {
super(context, layoutResourceId, trimmedData(data));
this.layoutResourceId = layoutResourceId;
this.context = context;
}
/**
* Copy data to a new array that has no nulls.
*/
private static Answer[] trimmedData(Answer[] data) {
Answer[] result = new Answer[data.length];
int n = 0;
for (Answer a : data) {
if (a != null) {
result[n++] = a;
}
}
if (n < data.length) {
result = Arrays.copyOf(result, n, Answer.class);
}
return result;
}
但是,如果您需要保持ListView
位置与原始data
数组之间的对应关系,则可能会导致代码中的其他位置出现问题。
另一方面:您可以取消getItemId()
方法; ArrayAdapter
中的默认实现完全相同。
答案 1 :(得分:-7)
只需更改此行.....
Answer data[] = null;
到
Answer[] data = null;