View Android Spinner data not updated for the selected item

I am trying to configure Spinner for multi-selection. I successfully made this multi-selectable, but when the item is reinstalled, the view inside the spinner is not updated.

Problem

When an item is re-selected in Spinner , the getView() SpinnerAdapter my SpinnerAdapter is called, it SpinnerAdapter View that I want, but that View somehow not displayed. I went through everything in the debugger, and I cannot find the difference between when another item is selected or the same item is re-selected. I went through all the code in Spinner AbsSpinner and AdapterView , and I cannot find what could be the reason for this.

Example

The rotator is filled with 6 items: Choice 1-6. A counter is generated with all items that are not selected. Choices 1, 2, and 4 are selected . Inside the plug, β€œSelect 1, Select 2, Select 4” is displayed.

FUgtzWy.png

Choice 4 is not selected (reselect in relation to Spinner). Choice 4 is correctly removed from the list, but the view inside the counter is not updated. It still displays "Select 1, Select 2, Select 4" . After going through the debugger, getView () on my SpinnerAdapter receives a call and all that. For some reason, the view is not actually displayed.

DXEzWu2.png

Option 2 is not selected (this is not a "re-selection" on Spinner). Here, everything functions as expected. Updated list items and view inside Spinner.

ssQGdia.png

Some code

Multipurpose 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; } } 

Spinner Adapter

Post important roles here. Leaving getters / setters etc.

 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; } } } 
+6
source share
2 answers

I know that it is very late, but I found a solution for the same problem as mine. Try adding adapter.notifyDataSetChanged() to your onItemSelected(AdapterView<?> parent, View view, int pos, long id) override onItemSelected(AdapterView<?> parent, View view, int pos, long id) .

My counter should show the default message until the user selects a value from it. It worked perfectly, if the user did not select the first item in the drop-down list, then the counter would not update itself. Added work adapter.notifyDataSetChanged() .

I also looked through some of the source codes, and I couldn’t know exactly what was going on, but I have an idea. Since Spinner does not call OnItemSelectedListener when selecting a value that has already been selected (unless you extend Spinner , which I did with this SO answer ), I assume that if you try to deselect your last selected value, Spinner will not recognize it as undo and therefore will not redraw the view. For you, selecting 1, 2, 4 in this order, then trying to deselect 4 will not lead to a second response, but then deselecting 2 will lead to redrawing.

I could be wrong, but I know that our problems were similar, and it worked for me.

+1
source

You need to update the view from the user interface thread. See this answer from another question, which is similar to yours, which updates the user interface stream in detail using AsyncTask:

fooobar.com/questions/109580 / ...

I had the same problem with a view not being updated by fragments, and I believe that this solution applies to this problem as well.

Hope this solves your problem!

0
source

Source: https://habr.com/ru/post/947867/


All Articles