我有一个 ListFragment(ListView 的行为应该相同)。列表项中有一些视图,包括微调器。
我想做的是在 Spinner 值发生变化时更新一些支持 ListFragment 适配器的数据。例如,如果 Spinner 在列表项 L[5] 中,并且在位置 1 处选择了 Spinner,我想更新支持数据 L[5].myVal = 1。然后我将调用 notifyDataSetChanged()适配器,以便它可以处理使用新 mVal 值的操作。
我已将 Spinner 包装在 SpinnerWithID 类中,该类将索引保存到与微调器关联的 L 数组中。我使用传入 getView() 的位置更新适配器 getView() 中的 ID。
我看到的问题是,当我的 SpinnerWithID onItemSelectedListener 被执行时,被选择的 SpinnerWithID 可能已被 ListFragment/ListView 回收用于列表中的另一个项目。
我的侦听器函数如下所示:
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() 返回一个意外的值,因为微调器本身可能已被回收用于列表中的另一个项目。
这是如何处理的?
编辑:我的 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 时,视图已被回收,因此附加到视图的标签已更改为新行。该死。