使用自定义适配器在一个列表视图中膨胀两个布局的问题

发布于 2024-11-29 06:20:18 字数 3037 浏览 1 评论 0原文

我在一个列表视图中膨胀两个布局。数据为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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷荒 2024-12-06 06:20:18

您的自定义适配器应重写方法 getViewTypeCount()getItemViewType (intposition)。现在,操作系统认为所有视图都具有相同的视图类型,因此它任意传递先前创建的视图。正如您所看到的,有时这不是该职位的正确视图。

Your custom adapter should override the methods getViewTypeCount() and getItemViewType (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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文