我的活动包含一个按钮和一个ListView。 ListView包含Spinner和EditText视图。每次我想在Activity的ListView中插入一个新的行条目时,我都会使用该按钮。
我已按照之前的stackoverflow线程的说明进行操作,如下所示:Android Listview with spinner and a checkbox关于如何使用像Spinners这样的可聚焦对象填充ListView。
我的问题是,每次在ListView中动态添加新的ListView条目时,前一个ListView条目的Spinner值都将丢失(实际上Spinner返回其默认设置)。为简单起见,我的Spinners填充了以下数据:
String spinner_data[] = {"apple", "banana", "pear", "watermelon", "strawberry"};
例如,如果我选择我的第一个ListView的Spinner值为“pear”,然后我使用Button添加一个新的ListView条目,则“pear”条目将从第一个ListView Spinner中消失,并出现默认值“apple” )。
感谢任何帮助!
这是我的活动:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv = (ListView) findViewById(R.id.lv);
da = new DataAdapter(this, new ArrayList<RawData>());
lv.setAdapter(da);
btn_new = (Button)findViewById(R.id.btn_new);
btn_new.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
da.add(new RawData(this));
da.notifyDataSetChanged();
}
});
}
RawData类就是这个:
public class RawData {
private int selected_position;
private ArrayAdapter<CharSequence> adapter;
public RawData(Context context)
{
adapter = ArrayAdapter.createFromResource(context, R.array.data, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}
public ArrayAdapter<CharSequence> getAdapter()
{
return adapter;
}
/**
* get adapter's item text from selected position
* @return
*/
public String getText()
{
return (String) adapter.getItem(selected_position);
}
public int getSelected()
{
return selected_position;
}
public void setSelected(int selected)
{
this.selected_position = selected;
}
}
DataArrayAdapter如下:
public class DataArrayAdapter extends ArrayAdapter<RawData> {
private Activity myContext;
//private final List<RawData> list;
public DataArrayAdapter(Activity context, List<RawData> list)
{
super(context, R.layout.row_view, list);
myContext = context;
}
static class ViewHolder
{
protected RawData data;
protected Spinner spn;
protected EditText edt;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view = null;
if ( convertView == null )
{
LayoutInflater inflator = myContext.getLayoutInflater();
view = inflator.inflate(R.layout.row_view, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.edt = (EditText)view.findViewById(R.id.edt);
viewHolder.data = new RawData(myContext);
viewHolder.spn = (Spinner)view.findViewById(R.id.spn);
viewHolder.spn.setAdapter(viewHolder.data.getAdapter());
viewHolder.spn.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2_position, long arg3) {
// TODO Auto-generated method stub
viewHolder.data.setSelected(arg2_position);
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
// Update the TextView to reflect what's in the Spinner
view.setTag(viewHolder);
}
else
{
view = convertView;
}
// This is what gets called every time the ListView refreshes
ViewHolder holder = (ViewHolder) view.getTag();
holder.spn.setSelection(getItem(position).getSelected());
return view;
}
}
答案 0 :(得分:4)
当getView
获得非空convertView
时,您无法处理这种情况。在您的示例中,在您添加项目后,ListView
会自行刷新,并且显示'pear'的位置会获得现有的convertView
(之前用于显示'apple'的那个),而您只是将其传递给ListView
而不设置当前位置的数据。您不能依赖ListView
项来存储任何数据,您应该始终在适配器的getView
方法中为位置设置正确的内容。
为了清楚起见,我看到你的代码在getView
的末尾设置了所选位置,但问题是当你的convertView通过getView
传递给ListView
时被标记到getView
1}}是随机的,可以与以前用于显示的任何位置相关联。
要使您的应用程序正常工作,您必须为所有微调器创建selectedItem值数组,并将其作为成员附加到适配器。您必须更新每个OnItemSelected事件的相应值,并为每个“添加”按钮单击添加新值。当您在{{1}}中准备视图时,您只需将选定的微调器索引设置为数组中的相应值。