Настройка spinner onClickListener() в Android
Я пытаюсь запустить onClickListener на Spinner, но я получаю следующую ошибку:
Java.lang.RuntimeException: "Не вызывайте setOnClickListener для AdapterView. Вероятно, вы хотите вместо setOnItemClickListener"
Я уверен, что хочу вызвать onClickListener и NOT onItemClickListener. Я нашел вопрос, заданный кем-то еще в Stack Overflow, Есть ли способ использовать setOnClickListener с Android Spinner?
В ответе говорится:
Вам нужно будет установить Click слушателя на базовом представлении (обычно TextView с id: android.R.id.text1) счетчика. к сделайте так:
Создайте собственный счетчик. конструктор (с атрибутами) создает прядильщик, поставляя макет android.R.layout.simple_spinner_item Сделайте findViewById (android.R.id.text1) для получения TextView Теперь установите onClickListener в TextView
Я пробовал ответ, отмеченный там, но он, похоже, не работает. Я получаю нулевой указатель на TextView после того, как я нахожу findViewById().
Это то, что я делаю:
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.layoutspinner,dataArray);
spinner.setAdapter(adapter);
TextView SpinnerText = (TextView)findViewById(R.id.spinnerText);
if (SpinnerText == null) {
System.out.println("Not found");
}
else {
SpinnerText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
//Do something
}
});
}
Файл layoutspinner.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/spinnerText"
android:singleLine ="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="6pt"
android:gravity="right"/>
Что я делаю неправильно?
Я новичок в Stack Overflow, я не нашел способа опубликовать дополнительный вопрос в другом потоке (или комментарий, так как я должен немного повторить), поэтому я начал новый вопрос.
По рекомендации Я пробовал это:
int a = spinnerMes.getCount();
int b = spinnerMes.getChildCount();
System.out.println("Count = " + a);
System.out.println("ChildCount = " + b);
for (int i = 0; i < b; i++) {
View v = spinnerMes.getChildAt(i);
if (v == null) {
System.out.println("View not found");
}
else {
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Click code
}
});
}
}
Но LogCat не показывает многообещающих результатов.
10-14 16:09:08.127: INFO/System.out(3116): Count = 7
10-14 16:09:08.127: INFO/System.out(3116): ChildCount = 0
Я тестировал это на уровнях API 7 и 8 с теми же результатами.
Ответы
Ответ 1
Следующее работает так, как вы этого хотите, но это не идеально.
public class Tester extends Activity {
String[] vals = { "here", "are", "some", "values" };
Spinner spinner;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
spinner = (Spinner) findViewById(R.id.spin);
ArrayAdapter<String> ad = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, vals);
spinner.setAdapter(ad);
Log.i("", "" + spinner.getChildCount());
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
int a = spinner.getCount();
int b = spinner.getChildCount();
System.out.println("Count =" + a);
System.out.println("ChildCount =" + b);
for (int i = 0; i < b; i++) {
View v = spinner.getChildAt(i);
if (v == null) {
System.out.println("View not found");
} else {
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("","click");
}
});
}
}
}
}, 500);
}
}
Позвольте мне точно знать, как вам нужно, чтобы spinner работал, и мы можем разработать лучшее решение.
Ответ 2
Вот рабочее решение:
Вместо установки счетчика OnClickListener мы устанавливаем OnTouchListener и OnKeyListener.
spinner.setOnTouchListener(Spinner_OnTouch);
spinner.setOnKeyListener(Spinner_OnKey);
и слушателей:
private View.OnTouchListener Spinner_OnTouch = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
doWhatYouWantHere();
}
return true;
}
};
private static View.OnKeyListener Spinner_OnKey = new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
doWhatYouWantHere();
return true;
} else {
return false;
}
}
};
Ответ 3
Всякий раз, когда вам нужно выполнить некоторые действия при нажатии Spinner в Android, используйте следующий метод.
mspUserState.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
doWhatIsRequired();
}
return false;
}
});
Одна вещь, о которой нужно помнить, - всегда возвращать False при использовании вышеуказанного метода. Если вы вернете True, выпадающие элементы счетчика не будут отображаться при нажатии на Spinner.
Ответ 4
Лично я использую это:
final Spinner spinner = (Spinner) (view.findViewById(R.id.userList));
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
userSelectedIndex = position;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Ответ 5
Прежде всего, счетчик не поддерживает события щелчка элемента. Вызов этого метода вызовет исключение.
Вы можете использовать setOnItemSelectedListener:
Spinner s1;
s1 = (Spinner)findViewById(R.id.s1);
int selectionCurrent = s1.getSelectedItemPosition();
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
if (selectionCurrent != position){
// Your code here
}
selectionCurrent= position;
}
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// Your code here
}
});
Ответ 6
Я предлагаю, чтобы все события для Spinner были разделены на два типа:
Я также предлагаю, чтобы, когда вы хотите поймать пользовательское событие, вы просто хотите избавиться от "программных событий". Так что это довольно просто:
private void setSelectionWithoutDispatch(Spinner spinner, int position) {
AdapterView.OnItemSelectedListener onItemSelectedListener = spinner.getOnItemSelectedListener();
spinner.setOnItemSelectedListener(null);
spinner.setSelection(position, false);
spinner.setOnItemSelectedListener(onItemSelectedListener);
}
Там ключевой момент: вам нужно setSelection (position, false). Параметр "false" в анимации немедленно активирует событие. Поведение по умолчанию заключается в том, чтобы перевести событие в очередь событий.