Android Spinner: избегайте onItemSelected вызовов во время инициализации
Я создал приложение для 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
}
}
11 ответов:
spinner.setOnItemSelectedListener(this); // Will call onItemSelected() Listener.
Так что первый раз обрабатывать это с любым целочисленным значением
пример: Первоначально Возьмите
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); } }
вы можете сделать это с помощью булевых значений, а также путем проверки текущих и предыдущих позиций. посмотреть здесь
просто поставьте эту строку перед set OnItemSelectedListener
spinner.setSelection(0,false)
передает
false
в качестве второго параметра выбор должен быть установлен без анимации изменения. Анимация вызовет задержку в заданном значении, что может привести к неожиданным результатам. А именно, установка прослушивателя после установки начального значения приведет к тому, что прослушиватель выбора элемента получит выбор, даже если выбор установлен до установки прослушивателя.
начиная с уровня API 3 вы можете использовать onUserInteraction() для действия с логическим значением, чтобы определить, взаимодействует ли пользователь с устройством.
http://developer.android.com/reference/android/app/Activity.html#onUserInteraction()
@Override public void onUserInteraction() { super.onUserInteraction(); userIsInteracting = true; }
в качестве поля для деятельности у меня есть:
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) { } });
когда вы приходите и проходите через действие, логическое значение сбрасывается в false. Работает как обаяние.
это сработало для меня
инициализация Spinner в Android иногда проблематична вышеуказанная проблема была решена с помощью этой модели.
Spinner.setAdapter(); Spinner.setSelected(false); // must Spinner.setSelection(0,true); //must Spinner.setonItemSelectedListener(this);
настройка адаптера должна быть первой частью, а onItemSelectedListener (this) будет последним при инициализации счетчика. По шаблону выше мой OnItemSelected () не вызывается во время инициализации spinner
хаха...У меня тот же вопрос. Когда initViews () просто сделать так.Последовательность-это ключ, слушатель-последний. Удачи Вам !
spinner.setAdapter(adapter); spinner.setSelection(position); spinner.setOnItemSelectedListener(listener);
мое решение:
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(); } }
вы можете сделать это таким образом:
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) { } });
сначала я создаю прослушиватель и приписываю переменному обратному вызову; затем я создаю второй анонимный прослушиватель, и когда это вызывается в первый раз, это изменяет прослушиватель =]
аналогичное простое решение, которое позволяет использовать несколько прядильщиков, заключается в том, чтобы поместить AdapterView в коллекцию - в суперкласс Activities - при первом выполнении onItemSelected(...) Затем проверьте, находится ли AdapterView в коллекции перед ее выполнением. Это позволяет один набор методов в суперклассе и поддерживает несколько AdapterViews и для этого несколько прядильщиков.
суперкласса ...
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.
}
была такая же проблема и это работает для меня:
У меня есть 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 предотвратит запуск спиннера onItemSelected сразу после того, как вы установите их ценности.
Если вам нужно обновить счетчик (после вызова сервера и т. д.) использовать removeSpinnersListeners() прямо перед вашими линиями обновления, и setSpinnersListeners() сразу после строк обновления. Это предотвратит запуск onItemSelected после обновления.
флаг взаимодействия с пользователем может быть установлен в true в методе onTouch и сброшен в
onItemSelected()
после того, как изменение выбора было обработано. Я предпочитаю это решение, потому что флаг взаимодействия с пользователем обрабатывается исключительно для счетчика, а не для других представлений в действии, которые могут повлиять на желаемое поведение.в коде:
создайте свой слушатель для spinner:
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);