ViewHolder для ListViews с различными макетами элементов

У меня есть ListView с двумя разными типами макета: один с изображением, а другой без изображения. Я пытаюсь сделать что-то вроде этого. Я переопределяю getView BaseAdapter:

public View getView(int position, View convertView, ViewGroup parent) {
        Map<String, String> item = mData.get(position);
        if(item.get("image_location").equals("") == true){
            ViewHolderWithoutImage holder = new ViewHolderWithoutImage();
            if(convertView == null){
                convertView = mInflater.inflate(R.layout.row_without_image, null);
                holder.title = (TextView)convertView.findViewById(R.id.title);
                holder.firstParagraph = (TextView)convertView.findViewById(R.id.first_paragraph);
                convertView.setTag(holder);
            }else{
                holder = (ViewHolderWithoutImage)convertView.getTag();
            }
            holder.title.setText(mData.get(position).get("title").toString());
            holder.firstParagraph.setText(item.get("first_paragraph").toString());

        }else{
            ViewHolderWithImage holder = new ViewHolderWithImage();
            Bitmap bm = null;
            if(convertView == null){
                convertView = mInflater.inflate(R.layout.row_with_image, null);
                holder.title = (TextView)convertView.findViewById(R.id.title_image);
                holder.firstParagraph = (TextView)convertView.findViewById(R.id.first_paragraph_image);
                holder.image = (ImageView)convertView.findViewById(R.id.image);
                convertView.setTag(holder);
            }else{
                holder = (ViewHolderWithImage)convertView.getTag();
            }

            holder.title.setText(mData.get(position).get("title").toString());
            holder.firstParagraph.setText(item.get("first_paragraph").toString());
            String location = imageBaseUrl + item.get("image_location");
            bm = downloadImage(location);
            holder.image.setImageBitmap(bm);
        }
        return convertView;
    }

Мои классы ViewHolder:

static class ViewHolderWithImage {
        TextView title;
        TextView firstParagraph;
        ImageView image;
    }

    static class ViewHolderWithoutImage {
        TextView title;
        TextView firstParagraph;
    }

Работает без второй части, но вылетает при переходе

holder = (ViewHolderWithImage)convertView.getTag();

частично когда item.get("image_location").equals("") != true с java.lang.reflect.InvocationTargetException. Любые идеи, как я могу это исправить?


person shtkuh    schedule 12.04.2011    source источник
comment
Попробуйте использовать getCause() или getTargetException() (см. здесь: download.oracle.com/javase/1.4.2/docs/api/java/lang/reflect/), чтобы получить дополнительную информацию об исключении.   -  person MByD    schedule 12.04.2011


Ответы (2)


Я думаю, это происходит потому, что тег convertView содержит ViewHolder другого типа. Попробуйте проверить convertView тип:

if(item.get("image_location").equals("") == true){
    ...
    if(convertView == null || !(convertView.getTag() instanceof ViewHolderWithoutImage)){
    ...
}else{
    ...
    if(convertView == null || !(convertView.getTag() instanceof ViewHolderWithImage)){
        convertView = mInflater.inflate(R.layout.row_with_image, null);
        ...

P.S. Лучше использовать системные методы для обработки разных макетов (переопределить getItemViewType()). На эту тему есть хорошая статья.

person Sergey Glotov    schedule 12.04.2011
comment
Последний фрагмент кода статьи неверен. Например, он не управляет этим случаем: convertView != null и в настоящее время создается экземпляр R.layout.item1, но для текущей позиции требуется R.layout.item2 - person Sébastien BATEZAT; 09.06.2015

Вы должны переопределить getItemViewType() и getViewTypeCount() в вашем адаптере, возвращая отдельный номер для каждого типа строки, например 0 для ViewHolderWithoutImage и 1 для ViewHolderWithImage. Таким образом, getView() сможет правильно решить, какое представление создавать.

person mugiwarapy    schedule 17.07.2014