1

行の種類 (4 種類の行) ごとに 4 つの異なるレイアウトを持つリストビューを設定しようとしています。ViewHolder を使用しています。

しかし、私は修正できない奇妙な問題を抱えています。私のビュー (4 つすべて) には CheckBox があり、いくつかの CheckBox をマークして無効にする必要があります。

私の問題はビューのリサイクルに関係していると思いますが、それが何であるかわかりません。
ここに私のコードの一部を投稿します:

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);
}

}


私の行の1つ(他の行は非常に似ていますが、UIがいくつか変更されています):

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;
    }
}

}

よろしくお願いいたします。

4

2 に答える 2

0

このコードは更新されていますか? あなたが私の質問に答えたとき、あなたは自分の見解をリサイクルしていないと言いました。しかし、ここで、convertView を ExtraRow 実装の getView メソッドに渡しているのがわかります。その getView 内では、null の場合は通常どおりにインフレートし、それ以外の場合は getTag を実行しています。

于 2013-10-24T13:22:26.737 に答える
0

ビューはそのままの状態でリサイクルされます。したがって、画面を離れるときにビューがチェックされた場合、システムがそれを再利用するときにチェックされるため (convertView)、明示的に再初期化する必要があります。

問題を引き起こす可能性のある別のことは、ViewHolder を定義する場所です。これは、クラス フィールドではなく、getView() のローカル変数である必要があります。で奇妙な動作が発生すると思いsetOnCheckedChangeListenerます。

于 2013-10-24T13:55:18.913 に答える