ViewHolders за ListView с различни оформления на елементи

Имам ListView с 2 различни типа оформление: едно с изображение и друго без изображение. Опитвам се да направя нещо като това. Заменям 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;
    }

Моите класове ViewHolders:

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