ListView的回收视图 [英] ListView recycling view

查看:252
本文介绍了ListView的回收视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个列表视图,每种类型行四种不同的布局(4种行),我使用ViewHolder。
搜索结果,但我发现一个奇怪的问题,我敢不能够解决的。
我的意见(所有4个),有一个复选框,一些复选框都被标记和残疾人,当我有这样的ListView有许多行和我滚动througth它,我的复选框越来越选中和未选中,启用和禁用...
搜索结果我相信我的问题已经是与回收利用的观点,但我没有收到那是什么。
结果我在这里发布一些我的code的:

I'm trying to set up a listview with four different layouts for each type of row (4 types of row), i'm using ViewHolder.

But i'm getting a weird problem which i'm not able to fix up. My views (all 4), have a CheckBox, some of the CheckBox have to be marked and disabled, when I have this listview with many rows and i scroll througth it, my CheckBox are getting checked and unchecked, enabled and disabled...

I belive my problem has something to do with recycling views, but i'm not getting what can it be.
Here i post some of my code:

class MyAdapter extends BaseAdapter {

private FragmentActivity activity;
private List<Extra> data;
private static LayoutInflater inflater=null;
private ManifestData manifest;
private Context context;

final List<ExtraRow> rows;

MyAdapter(List<Extra> extras, FragmentActivity activity, Context context) {
    rows = new ArrayList<ExtraRow>();
    this.activity = activity;
    this.context = context;

    for (Extra e : extras) {
        if (e.getPriceType()==1) {
            rows.add(new ExtraRowType1(LayoutInflater.from(context), e, activity));
        } else if (e.getPriceType()==2){
            rows.add(new ExtraRowType2(LayoutInflater.from(context), e, activity));
        } else if (e.getPriceType()==3){
            rows.add(new ExtraRowType3(LayoutInflater.from(context), e, activity));
        } else if (e.getPriceType()==4){
            rows.add(new ExtraRowType4(LayoutInflater.from(context), e, activity));
        }
    }
}

@Override
public int getViewTypeCount() {
    return 4;
}

@Override
public int getItemViewType(int position) {
    return rows.get(position).getViewType();
}

public int getCount() {
    return rows.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    return rows.get(position).getView(convertView);
}

}

结果我的一个行(其他的都非常相似,但一些用户界面的变化):


One of my rows (the others are very similar but with some UI changes):

public class ExtraRowType3 implements ExtraRow{
private final Extra extra;
private final LayoutInflater inflater;
final FragmentActivity activity;
private ViewHolder holder;

public ExtraRowType3(LayoutInflater inflater, Extra extra, FragmentActivity activity) {
    this.extra = extra;
    this.inflater = inflater;
    this.activity = activity;
}

@Override
public View getView(View convertView) {
    View view;

    if (convertView == null) {
        ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.reservas_extras_3, null);

        holder = new ViewHolder((TextView)viewGroup.findViewById(R.id.reservas_extras_titulo),
                                (CheckBox)viewGroup.findViewById(R.id.reservas_extras_3_checkbox),
                                (TextView)viewGroup.findViewById(R.id.reservas_extras_total));
        viewGroup.setTag(holder);
        view = viewGroup;
    } else {
        holder = (ViewHolder)convertView.getTag();
        view = convertView;
    }

    holder.title.setText(extra.getNombre());

    if(extra.isObligatorio()){
        holder.checkBox.setChecked(true);
        holder.checkBox.setClickable(false);
    }else{
        Disponibilidad d = Disponibilidad.getInstance();
        if(d.getExtraReserva(extra.getId())!=null){
            holder.checkBox.setChecked(true);
        }else{
            holder.checkBox.setChecked(false);
            holder.checkBox.setClickable(true);
        }
    }

    holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            ExtraReserva extraReserva = new ExtraReserva(extra.getId(), "", -1, -1, 1, extra.isSuplemento());
            Disponibilidad d = Disponibilidad.getInstance();
            if(isChecked){
                d.addExtra(extraReserva);
            }
            else d.deleteExtra(extraReserva.getIdExtra());
        }
    });

    return view;
}

@Override
public int getViewType() {
    return extra.getTipoPrecio();
}

private static class ViewHolder {
    final TextView title;
    final CheckBox checkBox;
    final TextView total;

    private ViewHolder(TextView title, CheckBox checkBox, TextView total) {
        this.title = title;
        this.checkBox = checkBox;
        this.total = total;
    }
}

}

感谢您对您的帮助提前。

Thank you for your help in advance.

推荐答案

您的观点是回收在他们离开的状态。因此,如果离开屏幕时,有人检查,它会在系统重新使用它(convertView)检查,因此必须明确地重新初始化。

Your views are recycled as in the state they were left. So if a view was checked when leaving the screen, it will be checked when the system re-uses it (the convertView) so it must be explicitely reinitialized.

这可能会导致问题Antoher事情是你定义你的ViewHolder。它应该是在你的getView(局部变量),而不是一类的字段。我猜它创建了怪异的行为 setOnCheckedChangeListener

Antoher thing that might cause problems is where you define your ViewHolder. It should be a local variable in your getView() and not a class field. I'm guessing it creates weird behaviour with setOnCheckedChangeListener.

这篇关于ListView的回收视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆