使用自定义适配器在一个列表视图中膨胀两个布局的问题
我在一个列表视图中膨胀两个布局。数据为json格式。我所做的是将 json 连接在一起,并检查每个布局的适当位置(第一个布局仅出现在位置 0 到第一个 json 的长度 - 1 之间)。
当列表视图变长时,问题就会出现,我可以向下滚动它。它出现了空指针异常。所以我注释了一些代码,错误就消失了。但我得到的并不是我所期望的: 它随机交换格式。 (假设第一个json的长度是x,所以0到x-1应该是第一个布局。但是当我向上和向下滚动时,有时0和x之间的某个位置更改为第二个布局。以及其他行> > x,有时更改为第一个布局)
这是适配器的代码,
public class CustomAdapter extends BaseAdapter {
private Activity activity;
private JSONArray data;
private static LayoutInflater inflater=null;
private SecondItem second_item;
private FirstItem first_item;
private int firstLength;
private boolean hasFirst = false;
public CustomAdapter(Activity a, JSONArray firstArray, JSONArray secondArray) {
activity = a;
first_item = new FirstItem (firstArray);
second_item = new SecondItem (secondArray);
firstLength = first_item.getLength();
if (!firstArray.isNull(0)) {
data=CustomUtils.concatJsonArray(firstArray, secondArray);
hasFirst = true;
}
else
data = secondArray;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
// TODO Auto-generated method stub
return data.length();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public static class ViewHolder{
public TextView txt_both;
public TextView txt_first_only;
...
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
ViewHolder holder;
if(convertView==null){
if (position < firstLength && hasFirst) {
vi = inflater.inflate(R.layout.first_item, null);
}
else {
vi = inflater.inflate(R.layout.second_item, null);
}
holder=new ViewHolder();
holder.txt_both=(TextView)vi.findViewById(R.id.txt_both);
...
if (position < firstLength && hasFirst) {
holder.txt_firstOnly=(TextView)vi.findViewById(R.id.txt_firstOnly);
...
}
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
if (position < firstLength && hasFirst) {
holder.txt_both.setText(first_item.getContent(position));
...
这里是注释块,这会导致之前的空指针异常(错误点是holder.txt_firstOnly.setText行):
/*if (first_item.getStatus(position)==0) {
holder.txt_firstOnly.setText(...);
}
else if (first_item.getStatus(position)==1) {
holder.txt_firstOnly.setText(...);
}
else if (first_item.getStatus(position)==2) {
holder.txt_firstOnly.setText(...);
} */
这是其余的代码:
}
else {
holder.txt_both.setText(second_item.getContent(position - firstLength));
...
}
return vi;
}
}
I'm inflating two layout in one listview. The data are in json format. What I do is I concat the json together, and check the appropriate position for each layout (the first layout only appear from position 0 to first-json's length - 1).
The problem arise when the list view get longer, and I can scroll down through it. It came out with a Null Pointer exception. So I commented some of the code, and the error disappear. But what I got is not really what I'm expecting:
It interchange the format randomly. (Assume the length of the first json is x, so 0 to x-1 should be the first layout. But when I scroll up & down, sometimes somewhere between 0 and x changed to second layout. As well as other row > x, sometimes changed to first layout)
Here's the code of the adapter
public class CustomAdapter extends BaseAdapter {
private Activity activity;
private JSONArray data;
private static LayoutInflater inflater=null;
private SecondItem second_item;
private FirstItem first_item;
private int firstLength;
private boolean hasFirst = false;
public CustomAdapter(Activity a, JSONArray firstArray, JSONArray secondArray) {
activity = a;
first_item = new FirstItem (firstArray);
second_item = new SecondItem (secondArray);
firstLength = first_item.getLength();
if (!firstArray.isNull(0)) {
data=CustomUtils.concatJsonArray(firstArray, secondArray);
hasFirst = true;
}
else
data = secondArray;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
// TODO Auto-generated method stub
return data.length();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public static class ViewHolder{
public TextView txt_both;
public TextView txt_first_only;
...
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
ViewHolder holder;
if(convertView==null){
if (position < firstLength && hasFirst) {
vi = inflater.inflate(R.layout.first_item, null);
}
else {
vi = inflater.inflate(R.layout.second_item, null);
}
holder=new ViewHolder();
holder.txt_both=(TextView)vi.findViewById(R.id.txt_both);
...
if (position < firstLength && hasFirst) {
holder.txt_firstOnly=(TextView)vi.findViewById(R.id.txt_firstOnly);
...
}
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
if (position < firstLength && hasFirst) {
holder.txt_both.setText(first_item.getContent(position));
...
here is the commented block, which causes null pointer exception before (The error point the line holder.txt_firstOnly.setText) :
/*if (first_item.getStatus(position)==0) {
holder.txt_firstOnly.setText(...);
}
else if (first_item.getStatus(position)==1) {
holder.txt_firstOnly.setText(...);
}
else if (first_item.getStatus(position)==2) {
holder.txt_firstOnly.setText(...);
} */
and here's the rest of the code :
}
else {
holder.txt_both.setText(second_item.getContent(position - firstLength));
...
}
return vi;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的自定义适配器应重写方法
getViewTypeCount()
和getItemViewType (intposition)
。现在,操作系统认为所有视图都具有相同的视图类型,因此它任意传递先前创建的视图。正如您所看到的,有时这不是该职位的正确视图。Your custom adapter should override the methods
getViewTypeCount()
andgetItemViewType (int position)
. Right now, the OS thinks all the views have the same view type, so it's arbitrarily passing in a previously created view. As you've seen, sometimes this isn't the right view for the position.