我有一个ListFragment(ListView应该表现相同)。 List项目中包含一些视图,包括Spinner。
我想要做的是在Spinner值发生变化时更新支持ListFragment适配器的一些数据。例如,如果Spinner在List项L [5]中,并且在位置1选择了Spinner,我想更新后备数据L [5] .myVal = 1.然后我将调用notifyDataSetChanged()适配器,以便它可以使用新的mVal值处理某些事情。
我将Spinner包装在SpinnerWithID类中,该类将索引保存到与微调器关联的L数组中。我使用传入getView()的位置更新适配器getView()中的ID。
我看到的问题是,当我的SpinnerWithID onItemSelectedListener被执行时,ListFragment / ListView可能已经为列表中的另一个项目回收了所选的SpinnerWithID。
我的监听器功能如下所示:
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
SpinnerWithID spinner = (SpinnerWithID)parent;
if (spinner != null) {
BackingData data = DataList.get(spinner.getListIndex());
// do something with data
}
}
因此,当调用它时,微调器的getListIndex()返回一个意外的值,因为微调器本身可能已被回收用于List中的另一个项目。
这是如何处理的?
编辑: 我的getView()看起来像这样:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder = new ViewHolder();
// First let's verify the convertView is not null
if (convertView == null) {
Context context = getContext();
SpinnerWithID mySpinner = new SpinnerWithID(context);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context,
R.array.spinner_array, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
mySpinner.setAdapter(adapter);
mySpinner.setOnItemSelectedListener(myFragment);
// Add things here to the view
myLayout.addView(mySpinner);
v.setTag(holder);
}
else {
holder = (ViewHolder) v.getTag();
}
// Update Views based on backing data
// Keep Spinner synced
holder.mySpinner.setListIndex(position);
return v;
}
编辑: 在buzeeg发布的链接之后,我的适配器代码现在看起来像这样:
public View getView(int position, View convertView, ViewGroup parent) {
// Build the view or use recycled view
holder.mySpinner.setTag( Integer.valueOf(position) );
holder.mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view,int pos, long id)
{
myListFragment.updateBackingData(((Integer)parent.getTag()).intValue(), pos);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
});
}
但是,我仍然有时会更新错误的后备数据项。我的猜测是,在调用onItemSelected时,视图已被回收,因此附加到视图的标记已更改为新行。织补。