Android:当我动态添加新的ListView条目时,ListView中的微调器会丢失它们的值

Android:当我动态添加新的ListView条目时,ListView中的微调器会丢失它们的值,android,listview,button,spinner,Android,Listview,Button,Spinner,我的活动包含一个按钮和一个列表视图。ListView包含一个微调器和一个EditText视图。每当我想在活动的ListView中插入新行条目时,我都会使用该按钮 我遵循了前面的stackoverflow线程的说明,比如这里的:关于如何使用可聚焦对象(如微调器)填充ListView 我的问题是,每次我在ListView中动态添加一个新的ListView条目时,前一个ListView条目的微调器值都会丢失,实际上微调器会返回到其默认设置。为简单起见,假设我的微调器中填充了以下数据: String

我的活动包含一个按钮和一个列表视图。ListView包含一个微调器和一个EditText视图。每当我想在活动的ListView中插入新行条目时,我都会使用该按钮

我遵循了前面的stackoverflow线程的说明,比如这里的:关于如何使用可聚焦对象(如微调器)填充ListView

我的问题是,每次我在ListView中动态添加一个新的ListView条目时,前一个ListView条目的微调器值都会丢失,实际上微调器会返回到其默认设置。为简单起见,假设我的微调器中填充了以下数据:

 String spinner_data[] = {"apple", "banana", "pear", "watermelon", "strawberry"};
例如,如果我选择我的第一个ListView微调器值为pear,然后用我的按钮添加一个新的ListView条目,pear条目将从第一个ListView微调器中消失,并显示默认值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;
}

 }

当getView获得非空convertView时,您没有处理这种情况。在您的示例中,添加项目后,ListView会刷新自身,并且应该显示“pear”的位置会获得一个现有的convertView,即以前用于显示“apple”的convertView,您只需将其传递给ListView,而不必设置当前位置的数据。您不能依赖ListView项来存储任何数据,您应该始终为适配器的getView方法中的位置设置正确的内容。 需要明确的是,我看到您的代码在getView的末尾设置了所选的位置,但问题是,当ListView中的回收器机制将标记到convertView的内容传递给getView时,标记到convertView的内容是随机的,并且可以与以前显示的任何位置相关联


要使应用程序正常工作,您必须为所有微调器创建selectedItem值数组,并将其作为成员附加到适配器。您必须更新每个OnItemSelected事件的相应值,并为每次单击add按钮添加新值。在getView中准备视图时,您只需将选定的微调器索引设置为数组中的相应值。

顺便说一句,您用来创建适配器的示例也坏了,我在那里也留下了一条消息。您好Vladimir,我决定在我的应用程序中采用不同的路径,并从列表视图中删除微调器。感谢您的关注:上帝保佑您,但您可以批准我的回答,因为它回答了您最初的问题。您对此仍有异议吗?