0

我对 Android 很陌生,目前在使用自定义列表适配器时遇到了一些问题。

基本上,我想制作一个问题列表,每个问题都有不同的类型(单选、复选框、文本、数字)。生成列表视图时,它显示正常。但是当我向下滚动时,顶部的项目会在底部重新生成。

我的代码是这样的:

public View getView(int position, View convertView, ViewGroup parent) {

  View someView = convertView;

  //get question type
  String type = questions.get(position)[2];

  //declare viewholder
  final ViewHolder holder;
  Log.i("Position", Integer.toString(position));

  if (someView == null) {
    Log.i("convertView", "null");
    holder = new ViewHolder();

    LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    someView = inflater.inflate(R.layout.list_survey, parent, false);

    TextView textView = (TextView) someView.findViewById(R.id.surveyQuestion);
    textView.setText(questions.get(position)[1]);

    LinearLayout optionContainer = (LinearLayout) someView.findViewById(R.id.surveyOption);

    int size = options.get(position).size();

    //radio button
    if (type.equals("radio")) {

        RadioGroup group = new RadioGroup(this.context);
        RelativeLayout.LayoutParams groupParam = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        optionContainer.addView(group, groupParam);
        RadioButton radio = null;

        ArrayList<RadioButton> radios = new ArrayList<RadioButton>();

        for (int i=0; i<size; i++){
            radio = new RadioButton(this.context);
            radio.setId(i+1);
            radio.setText(options.get(position).get(i)[1]);
            group.addView(radio);
            radios.add(radio);
        }      
        group.setOnCheckedChangeListener(new OnCheckedChangeListener() 
        {
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //Model element = (Model)group;
            }
        });

        holder.radiogroup = group;
        holder.radiobuttons = radios;

    //checkbox 
    } else if (type.equals("check")) {
        CheckBox checkbox = null;

        ArrayList<CheckBox> checks = new ArrayList<CheckBox>();

        for (int i=0; i<size; i++){
            checkbox = new CheckBox(this.context);
            checkbox.setId(i+1);
            checkbox.setText(options.get(position).get(i)[1]);
            optionContainer.addView(checkbox);
            checks.add(checkbox);
        }

        holder.checkboxes = checks;

    //textfield
    } else if (type.equals("txt")) {
        EditText field = null;

        ArrayList<EditText> fields = new ArrayList<EditText>();

        for (int i=0; i<size; i++){
            field = new EditText(this.context);
            field.setId(i+1);
            field.setHint(options.get(position).get(i)[1]);
            optionContainer.addView(field);
            fields.add(field);
        }

        holder.edittext = fields;
    //numeric
    } else if (type.equals("num")) {
        EditText field = null;

        ArrayList<EditText> fields = new ArrayList<EditText>();

        for (int i=0; i<size; i++){
            field = new EditText(this.context);
            field.setId(i+1);
            field.setHint(options.get(position).get(i)[1]);
            field.setInputType(InputType.TYPE_CLASS_NUMBER);
            optionContainer.addView(field);
            fields.add(field);
        }

        holder.edittext = fields;
    }

    someView.setTag(holder);

  } else {
    Log.i("convertView", "not null");
    holder = (ViewHolder) someView.getTag();
  }


    return someView;
}

viewHolder 类在这里:

//viewHolder
static class ViewHolder {
    ArrayList<CheckBox> checkboxes;
    ArrayList<EditText> edittext;
    RadioGroup radiogroup;
    ArrayList<RadioButton> radiobuttons;    
}

我究竟做错了什么?

我真的很感谢你的帮助。我已经搜索了一些其他解决方案,但我无法让它在我的代码上运行。

谢谢

4

1 回答 1

3

发生这种情况是因为您使用了convertViewandViewHolder不正确。向下滚动时,视图将被回收并且converView不会为空。该ViewHolder模式通常以这种方式使用:

public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null) {
        inflate the view
        create a ViewHolder and store the necessary views in it
        use setTag to store the ViewHolder in the convertView
    }
    else {
        use getTag to get the ViewHolder
    }
    update the views // <- you are not doing this when convertView != null
}

使用模式的原因convertView/ViewHolder是列表中的视图通常具有相同的布局,但其中显示的数据不同。本质上,convertView(当不为空时)是以前在列表中使用的视图,必须转换为显示该位置的正确数据。通过重用它,您可以避免昂贵的布局膨胀。这ViewHolder是进一步的优化,可以避免昂贵的findViewById调用。

于 2014-02-10T22:39:51.423 回答