проблема в раздувании двух макетов в одном списке с помощью специального адаптера - PullRequest
1 голос
/ 11 августа 2011

Я раздуваю два макета в одном списке. Данные в формате JSON. Что я делаю, так это соединяю json вместе и проверяю соответствующую позицию для каждого макета (первый макет отображается только от позиции 0 до длины первого json - 1).

Проблема возникает, когда представление списка становится длиннее, и я могу прокрутить его вниз. Это вышло с исключением Null Pointer. Поэтому я прокомментировал часть кода, и ошибка исчезла. Но то, что я получил, не совсем то, что я ожидал: Это меняет формат случайно. (Предположим, что длина первого 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;
}


}

1 Ответ

2 голосов
/ 12 августа 2011

Ваш пользовательский адаптер должен переопределять методы getViewTypeCount() и getItemViewType (int position). Сейчас ОС считает, что все представления имеют одинаковый тип представления, поэтому она произвольно передает ранее созданное представление. Как вы видели, иногда это неправильный взгляд на позицию.

...