Android spinner близко
У меня есть работа с прядильщиком, и мне было интересно, можно ли закрыть прядильщик программно, если пользователь открыл его.
Вся история заключается в том, что в фоновом режиме я запускаю процесс в отдельном потоке. Когда процесс завершен, я вызываю обработчик для основного действия и, в зависимости от результата, выполняю некоторые задачи. Именно тогда я хочу закрыть спиннер, это пользователь открыл его.Прядильщик находится в основном.XML расположение:
<Spinner android:id="@+id/birthPlaceSpinner" android:layout_weight="1"
android:layout_height="wrap_content" android:prompt="@string/select"
android:layout_width="fill_parent" />
И это обработчик:
private class BirthplaceChangedHandler extends Handler {
@Override
public void handleMessage(Message msg) {
String placeFilterStr = birthPlaceFilterText.getText().toString();
if ("".equals(placeFilterStr) || placeFilterStr == null || validNewAddresses.isEmpty()) {
birthPlaceSpinner.setEnabled(false);
hideGeoLocationInformation();
} else {
birthPlaceSpinner.setEnabled(true);
}
adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.multiline_spinner_dropdown_item, validNewAddressesStr)
birthPlaceSpinner.setAdapter(adapter);
}
}
Ура!
8 ответов:
Я не вижу способа сделать это-нет метода на
Spinner
, чтобы закрыть его. "Открытая" частьSpinner
- этоAlertDialog
на Android 1.x и 2.x, и я не совсем уверен, как это реализовано на Honeycomb при использовании голографической темы.Единственным обходным путем было бы клонировать исходный код для
Кроме того, я думаю, что то, что вы хотите, - это бедный UX. Если пользователь открылSpinner
и добавить в него некоторый код самостоятельно, чтобы закрыть диалоговое окно. Но, опять же, он не будет работать на Honeycomb или выше, пока вы не сможете увидеть и клонировать Этот код как хорошо.Spinner
, он, скорее всего, активно изучает содержимоеSpinner
и делает выбор. Выдернув его из-под пальца, вы в лучшем случае собьете их с толку. Пожалуйста, рассмотрите альтернативный подход.Также не используйте
getApplicationContext()
, Если вы не знаете , Почему вы используетеgetApplicationContext()
. Вы не нуждаетесь и даже не хотитеgetApplicationContext()
при созданииArrayAdapter
.
Это работает для меня:
class SomeAdapter extends BaseAdapter implements SpinnerAdapter { //...... public View getDropDownView(int position, View convertView, ViewGroup parent) { View view = convertView; if (view == null) { //...... } view.setOnClickListener(new ItemOnClickListener(parent)); return view; } //..... }
И слушатель щелчка:
class ItemOnClickListener implements View.OnClickListener { private View _parent; public ItemOnClickListener(ViewGroup parent) { _parent = parent; } @Override public void onClick(View view) { //....... // close the dropdown View root = _parent.getRootView(); root.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)); root.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)); } }
Ну, это немного сложнее, чем я думал.
Я добавляю здесь пошаговые детали. Постарайтесь следовать ему. Я смог достичь этого на уровне api 10.
И это решение предполагает, что вы должны закрыть диалоговое окно приглашения программно, когда пользователь нажимает на кнопку Home или если вы должны были перейти к следующему действию без взаимодействия с пользователем
Первым шагом является создание пользовательского прядильщика путем расширения класса прядильщика. Допустим, я создал класс CustomSpinner в упаковке кОм.БТС.sampleapp
Мой класс CustomSpinner выглядит следующим образом,
package com.bts.sampleapp; import android.content.Context; import android.util.AttributeSet; import android.widget.Spinner; public class CustomSpinner extends Spinner{ Context context=null; public CustomSpinner(Context context) { super(context); this.context=context; } public CustomSpinner(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public CustomSpinner(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); } }
Теперь в вашем Xml-файле замените элемент Spinner на этот пользовательский spinner,
<com.bts.sampleapp.CustomSpinner android:id="@+id/spin" android:layout_width="wrap_content" android:layout_height="wrap_content" />
Следующим шагом является инициализация и установка адаптера для этого spinner в вашем классе Activity,
Последний шаг-закрыть диалоговое окно, когда пользователь нажимает кнопку HomeButton или когда действие переходит в фоновый режим. Для этого мы переопределяем onPause () вот так,@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); CustomSpinner spin=null; spin=(CustomSpinner)findViewById(R.id.spin); spin.setAdapter(spinnerAdapter); //you can set your adapter here. }
@Override protected void onPause() { Log.i("Life Cycle", "onPause"); spin.onDetachedFromWindow(); super.onPause(); }
Теперь в onPause () вызовите метод
spin.onDetachedFromWindow();
, который выполняет работу по закрытию диалогового окна приглашения для вас.Теперь, как говорится, вызов
spin.onDetachedFromWindow();
из любой точки вашей деятельности должен помочь вам закрыть спиннер программно. Так что если это то, что вы хотите, то удалитеonpause()
.
public static void hideSpinnerDropDown(Spinner spinner) { try { Method method = Spinner.class.getDeclaredMethod("onDetachedFromWindow"); method.setAccessible(true); method.invoke(spinner); } catch (Exception e) { e.printStackTrace(); } }
Я думаю, что вы должны отказаться от использования
Spinner
и вместо этого использоватьImageView
С анимацией кадра (т. е.<animation-list>
), чтобы создать свой собственный спиннер. Вы просто устанавливаете фонImageView
, чтобы он был вашей анимацией кадра.Тогда вы можете легко сделать что-то , как это, чтобы начать и остановить его.
Как насчет клонирования нажатия клавиши "Назад"?
Хорошо, я только что попробовал
[current activity].dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_BACK));
И он не сделал ничего, что я мог видеть-затем нажал физическую клавишу Назад,и падение вниз ушло. Также попробовал сделать ACTION_UP сразу после падения-тоже никакого эффекта.
Вы хотели бы закрыть свои блесны отовсюду. Инъекция ключа для обратного нажатия-это хорошее решение, но здесь вы закрываете все виды сразу.
Как насчет setPressed (false)?
Ссылка: закрыть выпадающее меню Spinners, когда два из всех в groupview нажаты одновременноВ противном случае: Попробуйте сделать спиннер
focusable
иfocusableInTouchMode
, а также использоватьclearFocus()
на нем. Попробуйте сфокусироваться на виде под ним, используя методrequestFocus()
.Проверьте, если выпадающий список spinner закрывает