我正在尝试将 Spinner 自定义为多选。我已成功使其成为多选,但是当重新选择一个项目时,微调器内部的视图不会更新。
问题
当在 中重新选择一个项目时Spinner
,getView()
我SpinnerAdapter
的 被调用,产生View
我想要的,但View
不知何故不会显示。我已经逐步完成了调试器中的所有内容,我找不到选择不同项目或重新选择相同项目之间的任何差异。我已经浏览了所有代码,Spinner
AbsSpinner
但AdapterView
我找不到可能导致这种情况的原因。
例如
微调器包含 6 个项目:选项 1-6。微调器起源于所有未选择的项目。 选择了选项 1、2 和 4。微调器内的视图正确显示“Choice 1, Choice 2, Choice 4”。
选项 4 未选中(就 Spinner 而言,重新选择)。选项 4 已从列表中正确取消选中,但微调器内的视图不会更新。 它仍然显示 "Choice 1, Choice 2, Choice 4"。通过调试器,我的 SpinnerAdapter 上的 getView() 被调用,一切都被调用。由于某种原因,视图实际上并没有显示出来。
选项2 未选中(这不是 Spinner 的“重新选择”)。在这里,一切都按预期运行。Spinner 内的列表项和视图都会更新。
一些代码
多选微调器
public class MultiSelectSpinner extends Spinner {
private OnItemSelectedListener listener;
public MultiSelectSpinner(Context context) {
super( context );
}
public MultiSelectSpinner(Context context, AttributeSet attrs) {
super( context, attrs );
}
public MultiSelectSpinner(Context context, AttributeSet attrs, int defStyle) {
super( context, attrs, defStyle );
}
@Override
public void setSelection( int position ) {
super.setSelection( position );
if ( listener != null ) {
listener.onItemSelected( this, getSelectedView(), position, getAdapter().getItemId( position ) );
}
}
public void setOnItemSelectedEvenIfUnchangedListener( OnItemSelectedListener listener ) {
this.listener = listener;
}
}
微调适配器
只在这里发布重要的部分。省略 getter/setter 等。
public class FormChoiceSpinnerAdapter implements SpinnerAdapter, OnItemSelectedListener {
private Choice[] choices;
private String title;
private final DataSetObservable dataSetObservable = new DataSetObservable();
public FormChoiceSpinnerAdapter(String[] choices, String title) {
setChoices( new Choice[choices.length] );
for (int i = 0; i < choices.length; i++) {
getChoices()[i] = new Choice( choices[i] );
}
}
@Override
public View getView( int position, View convertView, ViewGroup parent ) {
Context context = parent.getContext();
if ( convertView == null ) {
convertView = LayoutInflater.from( context ).inflate( android.R.layout.simple_spinner_item, parent, false );
}
String displayString = "";
for (int i = 0; i < getChoices().length; i++) {
Choice choice = getChoices()[i];
if ( choice.isSelected() ) {
displayString += choice.getLabel() + ", ";
}
}
if ( displayString.length() > 0 ) {
displayString = displayString.trim().substring( 0, displayString.length() - 2 );
}
else {
displayString = getTitle() + "...";
}
( (TextView) convertView ).setText( displayString );
return convertView;
}
@Override
public View getDropDownView( int position, View convertView, ViewGroup parent ) {
Context context = parent.getContext();
if ( convertView == null ) {
convertView = LayoutInflater.from( context ).inflate( R.layout.simple_dropdown_item, parent, false );
}
Choice choice = getChoices()[position];
TextView text = (TextView) convertView.findViewById( android.R.id.text1 );
text.setText( choice.getLabel() );
ImageView selectedImage = (ImageView) convertView.findViewById( R.id.image_selected );
int visibility = choice.isSelected() ? View.VISIBLE : View.GONE;
selectedImage.setVisibility( visibility );
return convertView;
}
@Override
public void onItemSelected( AdapterView<?> parent, View view, int position, long id ) {
Choice choice = getChoices()[position];
choice.setSelected( !choice.isSelected() );
ImageView imageView = (ImageView) view.findViewById( R.id.image_selected );
if ( imageView != null ) {
imageView.setVisibility( choice.isSelected() ? View.VISIBLE : View.GONE );
}
}
@Override
public void onNothingSelected( AdapterView<?> parent ) {
//No op
}
public static class Choice {
private boolean selected;
private String label;
public Choice(String label) {
this.label = label;
selected = false;
}
}
}