Android Spinner数据视图未在重新选择的项目上更新

Android Spinner数据视图未在重新选择的项目上更新,android,android-spinner,Android,Android Spinner,我正在尝试将微调器自定义为多选项。我已经成功地将其设置为多选项,但是当重新选择某个项目时,微调器内部的视图不会得到更新 问题 在微调器中重新选择项目时,调用我的微调器的getView(),生成我想要的视图,但该视图无法显示。我已经在调试器中完成了所有操作,但在选择不同项或重新选择相同项时,我找不到任何差异。我已经查看了SpinnerAbsSpinner和AdapterView中的所有代码,但我找不到可能的原因 例如 微调器中填充了6项:选项1-6。微调器在所有未选中项的情况下启动。选择选项1、2

我正在尝试将微调器自定义为多选项。我已经成功地将其设置为多选项,但是当重新选择某个项目时,微调器内部的视图不会得到更新

问题 在
微调器中重新选择项目时,调用我的
微调器的
getView()
,生成我想要的
视图
,但该
视图
无法显示。我已经在调试器中完成了所有操作,但在选择不同项或重新选择相同项时,我找不到任何差异。我已经查看了
Spinner
AbsSpinner
AdapterView
中的所有代码,但我找不到可能的原因

例如 微调器中填充了6项:选项1-6。微调器在所有未选中项的情况下启动。选择选项1、2和4。微调器内的视图将正确显示“选项1、选项2、选项4”

未选择选项4(就微调器而言,重新选择)。选项4已从列表中正确取消选中,但微调器内的视图不会更新。它仍然显示“选项1、选项2、选项4”。通过调试器,我的SpinnerAdapter上的getView()将被调用,所有内容都将被调用。由于某些原因,视图实际上无法显示

未选择选项2(这不是微调器的“重新选择”)。在这里,一切正常。微调器中的列表项和视图都将更新

一些代码 多选择微调器 旋转接头 只在这里张贴重要的文章。省略了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;
        }
    }
}
公共类FormChoiceSpinnerAdapter实现SpinnerAdapter,OnItemSelectedListener{
私人选择[]选择;
私有字符串标题;
private final DataSetObservable DataSetObservable=新DataSetObservable();
public FormChoiceSpinnerAdapter(字符串[]选项,字符串标题){
setChoices(新选项[choices.length]);
for(int i=0;i0){
displayString=displayString.trim().substring(0,displayString.length()-2);
}
否则{
displayString=getTitle()+“…”;
}
((TextView)convertView.setText(displayString);
返回视图;
}
@凌驾
公共视图getDropDownView(int位置、视图转换视图、视图组父视图){
Context=parent.getContext();
if(convertView==null){
convertView=LayoutInflater.from(context).充气(R.layout.simple\u下拉菜单项,父项,false);
}
Choice=getChoices()[position];
TextView text=(TextView)convertView.findViewById(android.R.id.text1);
text.setText(choice.getLabel());
ImageView selectedImage=(ImageView)convertView.findViewById(R.id.image\u selected);
int visibility=choice.isSelected()?View.visibility:View.GONE;
选择edimage.setVisibility(可见性);
返回视图;
}
@凌驾
已选择公共视图(AdapterView父视图、视图视图、整型位置、长id){
Choice=getChoices()[position];
choice.setSelected(!choice.isSelected());
ImageView ImageView=(ImageView)view.findViewById(R.id.image\u选中);
如果(imageView!=null){
imageView.setVisibility(choice.isSelected()?View.VISIBLE:View.GONE);
}    
}
@凌驾
未选择公共无效(AdapterView父级){
//无操作
}
公共静态类选择{
选择私有布尔值;
私有字符串标签;
公共选择(字符串标签){
this.label=标签;
所选=假;
}
}
}

您需要从UI线程更新视图。请参阅另一个问题的答案,该问题与您的问题类似,其中详细说明了使用异步任务更新UI线程:

我有相同的问题,目的是不使用片段更新,我相信这个解决方案也适用于这个问题


我希望这能解决你的问题

我知道现在已经很晚了,但我找到了一个解决类似问题的方法。尝试将
adapter.notifyDataSetChanged()
添加到您的
onItemSelected(AdapterView父项、视图视图、int pos、长id)
覆盖方法

我的微调器应该显示一条默认消息,直到用户实际从中选择一个值为止。除非用户选择下拉列表中的第一项,否则它工作正常,然后微调器将不会自我更新。添加
适配器。notifyDataSetChanged()
有效

我还浏览了一些源代码,但找不到到底发生了什么,但我有一个想法。由于
微调器
在选择已选择的值时不会调用
OnItemSelectedListener
(除非您扩展
微调器
,我是在的帮助下完成的),我猜如果您尝试取消选择最近选择的值,
微调器
不会将其视为取消选择,因此,我们不会
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;
        }
    }
}