我对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;
}
我做错了什么?
我非常感谢你的帮助。我已经搜索了其他一些解决方案,但我的代码无法解决。
由于
答案 0 :(得分:3)
之所以发生这种情况,是因为您错误地使用了convertView
和ViewHolder
。向下滚动时,视图将被回收,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
来电。