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

Jam*_*ken 6 android android-spinner

我正在尝试将Spinner自定义为多选.我已经成功地使它可以多选,但是当重新选择一个项时,微调器内部的视图不会更新.

问题

当一个项目重新被选中时Spinner,getView()我的SpinnerAdapter被调用产生了View我想要它的东西,但是View不知怎的,它不会被显示出来.我已经完成了调试器中的所有操作,并且在选择不同的项目或重新选择相同的项目时,我找不到任何差异.我已经浏览了所有的代码Spinner AbsSpinner,AdapterView而且我找不到可能导致这种情况的原因.

例如

微调器有6个项目:选择1-6.微调器起源于未选中的所有项目. 选择选项1,2和4.微调器内的视图正确显示"选择1,选择2,选择4".

选择4未被选中(就Spinner而言,重选).从列表中正确取消选中选项4,但微调器内的视图不会更新. 它仍然显示"选择1,选择2,选择4".单步执行调试器,我的SpinnerAdapter上的getView()会被调用.出于某种原因,View实际上并未显示.

选择2未被选中(这不是对Spinner的"重新选择").这里的一切都按预期运作.列表项和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;
    }
}
Run Code Online (Sandbox Code Playgroud)

旋转适配器

只在这里发布重要的部分.留出吸气剂/安装者等

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ali*_*son 0

您需要从 UI 线程更新视图。请参阅另一个与您的问题类似的问题的答案,其中详细介绍了使用 AsyncTask 更新 UI 线程:

/sf/answers/305954981/

我遇到了同样的问题,视图不更新片段,我相信这个解决方案也适用于这个问题。

我希望这能解决您的问题!