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 86

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);

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

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