Android Spinner: избегать onItemВыбранные вызовы во время инициализации

Я создал приложение для Android со Spinner и TextView. Я хочу отобразить выбранный элемент из выпадающего списка Spinner в TextView. Я реализовал Spinner в методе onCreate поэтому, когда я запускаю программу, она показывает значение в TextView (перед выбором элемента из выпадающего списка).

Я хочу показать значение в TextView только после выбора элемента из выпадающего списка. Как мне это сделать?

Вот мой код:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class GPACal01Activity extends Activity implements OnItemSelectedListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Spinner spinner = (Spinner) findViewById(R.id.noOfSubjects);

        // Create an ArrayAdapter using the string array and a default spinner layout
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.noofsubjects_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
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(this);
    }

    public void onItemSelected(AdapterView<?> parent, View arg1, int pos,long id) {
        TextView textView = (TextView) findViewById(R.id.textView1);
        String str = (String) parent.getItemAtPosition(pos);
        textView.setText(str);
    }

    public void onNothingSelected(AdapterView<?> arg0) {
        // TODO Auto-generated method stub

    }
}

Ответ 1

spinner.setOnItemSelectedListener(this); // Will call onItemSelected() Listener.

Итак, сначала обработайте это с любым значением Integer

Пример:  Первоначально Take int check = 0;

public void onItemSelected(AdapterView<?> parent, View arg1, int pos,long id) {
   if(++check > 1) {
      TextView textView = (TextView) findViewById(R.id.textView1);
      String str = (String) parent.getItemAtPosition(pos);
      textView.setText(str);
   }
}

Вы можете сделать это с помощью логического значения, а также путем проверки текущей и предыдущей позиций. Смотрите здесь

Ответ 2

Просто поставьте эту строку перед установкой OnItemSelectedListener

spinner.setSelection(0,false)

Ответ 3

Начиная с уровня API 3, вы можете использовать onUserInteraction() для Activity с логическим значением, чтобы определить, взаимодействует ли пользователь с устройством.

http://developer.android.com/reference/android/app/Activity.html#onUserInteraction()

@Override
public void onUserInteraction() {
     super.onUserInteraction();
     userIsInteracting = true;
}

В качестве поля в Activity я:

 private boolean userIsInteracting;

Наконец, мой счетчик:

      mSpinnerView.setOnItemSelectedListener(new OnItemSelectedListener() {

           @Override
           public void onItemSelected(AdapterView<?> arg0, View view, int position, long arg3) {
                spinnerAdapter.setmPreviousSelectedIndex(position);
                if (userIsInteracting) {
                     updateGUI();
                }
           }

           @Override
           public void onNothingSelected(AdapterView<?> arg0) {

           }
      });

Когда вы приходите и проходите через операцию, логическое значение reset равно false. Работает как шарм.

Ответ 4

Это сработало для меня

Инициализация Spinner в Android иногда проблематична эта проблема была решена этой схемой.

Spinner.setAdapter();
Spinner.setSelected(false);  // must
Spinner.setSelection(0,true);  //must
Spinner.setonItemSelectedListener(this);

Адаптер настройки должен быть первым, а onItemSelectedListener (это) будет последним при инициализации счетчика. По шаблону выше мой OnItemSelected() не вызывается во время инициализации spinner

Ответ 5

Ха-ха... У меня такой же вопрос. Когда initViews() просто делает это. Последовательность - это ключ, слушатель - последний. Удачи!

spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);

Ответ 6

Мое решение:

protected boolean inhibit_spinner = true;


@Override
        public void onItemSelected(AdapterView<?> arg0, View arg1,
                int pos, long arg3) {

            if (inhibit_spinner) {
                inhibit_spinner = false;
            }else {

            if (getDataTask != null) getDataTask.cancel(true);
            updateData();
            }

        }

Ответ 7

Вы можете сделать это следующим образом:

AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            //set the text of TextView
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

yourSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            yourSpinner.setOnItemSelectedListener(listener);
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

Сначала я создаю прослушиватель и приписывается переменному обратному вызову; то я создаю второго слушателя анонимным, и когда это вызывается в первый раз, это изменяет слушателя =]

Ответ 8

Флаг взаимодействия пользователя может быть установлен в true в методе onTouch и reset в onItemSelected() после того, как было изменено изменение выбора. Я предпочитаю это решение, потому что флаг взаимодействия с пользователем обрабатывается исключительно для счетчика, а не для других видов активности, которые могут повлиять на желаемое поведение.

В коде:

Создайте свой слушатель для счетчика:

public class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener {

    boolean userSelect = false;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        userSelect = true;
        return false;
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
        if (userSelect) { 
            userSelect = false;
            // Your selection handling code here
        }
    }

}

Добавьте слушателя к счетчику как как OnItemSelectedListener, так и OnTouchListener:

SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);

Ответ 9

Чтобы избежать вызова spinner.setOnItemSelectedListener() во время инициализации

spinner.setSelection(Adapter.NO_SELECTION, true); //Add this line before setting listener
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
});

Ответ 10

Аналогичное простое решение, которое позволяет нескольким прядильщикам, заключается в том, чтобы поместить AdapterView в коллекцию - в суперкласс класса Activities - при первом выполнении onItemSelected (...) Затем проверьте, находится ли AdaptView в коллекции перед его выполнением. Это позволяет использовать один набор методов в суперклассе и поддерживает несколько адаптеров и, следовательно, несколько конвейеров.

Суперкласс...

private Collection<AdapterView> AdapterViewCollection = new ArrayList<AdapterView>();

   protected boolean firstTimeThrough(AdapterView parent) {
    boolean firstTimeThrough = ! AdapterViewCollection.contains(parent);
    if (firstTimeThrough) {
       AdapterViewCollection.add(parent);
     }
    return firstTimeThrough;
   }

Подкласс...

public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
      if (! firstTimeThrough(parent)) {
        String value = safeString(parent.getItemAtPosition(pos).toString());
        String extraMessage = EXTRA_MESSAGE;
        Intent sharedPreferencesDisplayIntent = new         Intent(SharedPreferencesSelectionActivity.this,SharedPreferencesDisplayActivity.class);
    sharedPreferencesDisplayIntent.putExtra(extraMessage,value);
    startActivity(sharedPreferencesDisplayIntent);
  }
  // don't execute the above code if its the first time through
  // do to onItemSelected being called during view initialization.

}

Ответ 11

создать логическое поле

private boolean inispinner;

внутри создания деятельности

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if (!inispinner) {
                inispinner = true;
                return;
            }
            //do your work here
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

Ответ 12

Попробуй это

spinner.postDelayed(new Runnable() {
        @Override
        public void run() {
            addListeners();
        }
    }, 1000);.o

Ответ 13

Вы можете достичь этого с помощью setOnTouchListener сначала, затем setOnItemSelectedListener в onTouch

@Override
public boolean onTouch(final View view, final MotionEvent event) {
 view.setOnItemSelectedListener(this)
 return false;
}

Ответ 14

Это сработало для меня:

    spinner.setSelection(0, false);
    new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                spinner.setOnItemSelectedListener(listener);
            }, 500);

Ответ 15

Была та же проблема, и это работает для меня:

У меня есть 2 прядильника, и я обновляю их во время init и во время взаимодействия с другими элементами управления или после получения данных с сервера.

Вот мой шаблон:

public class MyClass extends <Activity/Fragment/Whatever> implements Spinner.OnItemSelectedListener {

    private void removeSpinnersListeners() {
        spn1.setOnItemSelectedListener(null);
        spn2.setOnItemSelectedListener(null);
    }

    private void setSpinnersListeners() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                spn1.setOnItemSelectedListener(MyClass.this);
                spn2.setOnItemSelectedListener(MyClass.this);
            }
        }, 1);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        // Your code here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
}

При запуске класса используйте setSpinnersListeners() вместо прямой установки слушателя.

Runnable предотвратит запуск spinner onItemSelected сразу после того, как вы установили свои значения.

Если вам нужно обновить счетчик (после вызова сервера и т.д.), используйте removeSpinnersListeners() прямо перед вашими линиями обновления и setSpinnersListeners() сразу после обновления линий. Это предотвратит запуск onItemSelected после обновления.

Ответ 16

На основании ответа Абхи я сделал этого простого слушателя

class SpinnerListener constructor(private val onItemSelected: (position: Int) -> Unit) : AdapterView.OnItemSelectedListener {

    private var selectionCount = 0

    override fun onNothingSelected(parent: AdapterView<*>?) {
        //no op
    }

    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        if (selectionCount++ > 1) {
           onItemSelected(position)
        }
    }
}

Ответ 17

Код

spinner.setOnTouchListener(new View.OnTouchListener() { 
@Override public boolean onTouch(View view, MotionEvent motionEvent) { isSpinnerTouch=true; return false; }});

holder.spinner_from.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int slot_position, long l) {
                if(isSpinnerTouch)
                {
                    Log.d("spinner_from", "spinner_from");
                    spinnerItemClickListener.onSpinnerItemClickListener(position, slot_position, AppConstant.FROM_SLOT_ONCLICK_CODE);
                }
                else {

                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {

            }
        });