Шаблон ViewHolder с пользовательскими представлениями дублирует представление списка

@Override
public View getView(int position, View convertView, ViewGroup parent) 
{
    ViewHolder holder;
    if ( convertView == null ) 
    {
        holder = new ViewHolder();
        View custView = new CustomView(false,  this.getItem(position), mContext, position).getView();
        holder.customView = custView;
        custView.setTag( holder );
    }
    else
    {
        holder = (ViewHolder) convertView.getTag();
        custView = holder.customView;
    }
    return custView ;   
}



private static class ViewHolder 
{
    View customView;
}

Это часть CustomView:

    public View getView() {
        return mDataViewRoot;
    }

    public CustomView(boolean cameFromA, CustomDataClass customDataObject, Context ctx, int position) {
        super();
        this.cameFromA= cameFromA;
        this.customDataObject= customDataObject;
        this.mContext = ctx;
        this.mPosition = position;
        LayoutInflater inflater = LayoutInflater.from(ctx);
        mDataViewRoot = inflater.inflate(R.layout.view_root, null);
        mViewsHolder = (LinearLayout) mDataViewRoot.findViewById(R.id.data_holder);
        determineState(source);
        prepareView();
        handleCornerArea();
    }

Я хотел реализовать держатель для представления по причинам производительности (и лучшего дизайна). Однако, это заканчивает тем, что испортило мой список, дублируя представления..

1 ответ

Я предполагаю, что вы настраиваете данные своих просмотров в CustomView. Не делайте так, вам нужно установить данные представлений в методе getView этого адаптера.

Вот правильный способ использовать шаблон держателя вида:

@Override
public View getView(int position, View convertView, ViewGroup parent) 
{
    ViewHolder holder;
    if ( convertView == null ) {
        holder = new ViewHolder();
        // I don't know what you are doing with the boolean value, item or position...
        convertView = new CustomView(false,  this.getItem(position), mContext, position).getView();
        holder.mCustomViewsTextView = (TextView) convertView.findViewById(R.id.customTextView);
        convertView.setTag( holder );
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.mCustomViewsTextView.setText = "Item position: " + position;

    return convertView;   
}

private static class ViewHolder {
    TextView mCustomViewsTextView;
    // Other views that are in your CustomView
    // ...
}


РЕДАКТИРОВАТЬ 1:
Если вы не хотите делать это таким образом, вы должны добавить установщики в свой CustomView и вызвать их из метода getView. Что я пытаюсь сказать, что вам нужно обновить данные CustomView в методе getView, если вы этого не сделаете, то вы получили результаты, что происходит потом...


РЕДАКТИРОВАТЬ 2:
Нет никакого смысла в вашем шаблоне держателя вида, вы можете просто сделать это так:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    CustomView customView = (CustomView) convertView;
    if (customView == null ) {
        customView = new CustomView(false,  this.getItem(position), mContext, position).getView();
    }

    // You need to add these setters to your CustomView
    customView.setCustomDataObject(this.getItem(position));
    customView.setPosition(position);
    customView.setCameFromA(false);

    return customView;   
}
Другие вопросы по тегам