Android Spinner закрыть

У меня есть активность со счетчиком, и мне было интересно, можно ли программно закрыть счетчик, если пользователь открыл его.

Вся история в том, что в фоновом режиме я запускаю процесс в отдельном потоке. Когда процесс завершается, я вызываю обработчик для основного действия и, в зависимости от результата, выполняю некоторые задачи. Именно тогда я хочу закрыть счетчик, если пользователь открыл его.

Счетчик находится в макете main.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);
    }
}

Ваше здоровье!


person Markos Fragkakis    schedule 02.09.2011    source источник
comment
Как вы создаете / запускаете спиннер? То, что вы хотите сделать, почти наверняка возможно, но вы не предоставили достаточно информации, чтобы ответить на свой вопрос. Фрагменты кода помогают.   -  person i_am_jorf    schedule 02.09.2011
comment
Заменить Spinner.onDetachedFromWindow, сделать его общедоступным и вызвать вручную было единственным способом, который сработал для меня. Я подписался на stackoverflow.com/a/21122845/369317   -  person Denis Kniazhev    schedule 14.10.2014


Ответы (8)


Я не вижу способа сделать это - на Spinner нет способа закрыть его. «Открытая» часть Spinner - это AlertDialog на Android 1.x и 2.x, и я не совсем уверен, как это реализовано в Honeycomb при использовании голографической темы.

Единственный обходной путь - клонировать исходный код для Spinner и самостоятельно добавить код, чтобы закрыть диалоговое окно. Но, опять же, это не будет работать на Honeycomb или более поздних версиях, пока вы не увидите и не клонируете этот код.

Кроме того, я думаю, что вам нужен плохой UX. Если пользователь открыл Spinner, он, скорее всего, активно изучает содержимое Spinner и делает выбор. Выдергивание этого из-под пальца в лучшем случае их запутает. Пожалуйста, рассмотрите альтернативный подход.

Кроме того, не используйте getApplicationContext(), если вы не знаете почему используете getApplicationContext(). Вам не нужно и даже не нужно getApplicationContext() при создании ArrayAdapter.

person CommonsWare    schedule 02.09.2011

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

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));
    }
}
person ayepin    schedule 30.03.2013

Ну, это немного сложнее, чем я думал.

Я добавляю сюда пошаговые инструкции. Попробуйте следовать ему. Я смог добиться этого на уровне API 10.

И это решение предполагает, что вы должны программно закрывать диалоговое окно с запросом, когда пользователь нажимает кнопку «Домой» или если вам нужно было перейти к следующему действию без взаимодействия с пользователем

Первым шагом является создание Custom Spinner путем расширения класса Spinner. Допустим, я создал класс под названием CustomSpinner в пакете com.bts.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 этим настраиваемым счетчиком,

        <com.bts.sampleapp.CustomSpinner
        android:id="@+id/spin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Следующим шагом является инициализация и установка адаптера для этого счетчика в вашем классе Activity,

    @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.
}

Последний шаг - закрыть диалоговое окно, когда пользователь нажимает кнопку HomeButton или когда действие переходит в фоновый режим. Для этого мы переопределяем onPause () следующим образом:

@Override
    protected void onPause() {
        Log.i("Life Cycle", "onPause");
        spin.onDetachedFromWindow();
        super.onPause();
    }

Теперь внутри onPause () вызовите метод spin.onDetachedFromWindow();, который закрывает диалоговое окно подсказки за вас.

Теперь, как уже было сказано, вызов spin.onDetachedFromWindow(); из любого места в вашей деятельности должен помочь вам программно закрыть счетчик. Так что, если это то, что вы хотите, удалите onpause().

person Andro Selva    schedule 06.08.2013

Я думаю, вам следует отказаться от использования Spinner и вместо этого использовать ImageView с Анимация кадра (т. Е. <animation-list>) для создания собственного счетчика. Вы просто устанавливаете фон ImageView так, чтобы его можно было рисовать в анимации кадра.

Тогда вы можете легко сделать что-то подобное, чтобы начать и останови это.

person i_am_jorf    schedule 02.09.2011

Вы хотите закрыть свои спиннеры откуда угодно. Внедрение клавиш для нажатия BACK - хорошее решение, но здесь вы закрываете все представления сразу.

Как насчет setPressed (false)?
Ссылка: Закрыть раскрывающийся список Spinners при одновременном нажатии двух из всех в групповом просмотре

В противном случае: попробуйте сделать Spinner focusable и focusableInTouchMode и используйте на нем clearFocus(). Попытайтесь сфокусироваться на представлении под ним, используя метод requestFocus().

Проверьте, закрывается ли раскрывающийся список счетчика

person Abhinav Saxena    schedule 09.06.2014

Используйте clearFocus(), чтобы программно закрыть счетчик

spinner.clearFocus();
person Vikas Kumbhar    schedule 22.04.2015

Добавьте в код clearfocus ().

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

Использовать прозрачный фон в xml

android:background="@android:color/transparent

<Spinner 
    android:id="@+id/spinner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/transparent"
    android:clickable="false"
    android:focusable="?android:attr/windowOverscan"
    android:focusableInTouchMode="false"
    android:pointerIcon="arrow"
    android:spinnerMode="dialog"
    android:theme="@style/ThemeOverlay.AppCompat.Light" />
person Sagittarius    schedule 31.03.2020

person    schedule
comment
Я то, что мне нужно. - person rodrigo.oliveira; 04.09.2018
comment
Плавно и просто !! 1 большое спасибо! 1 - person Parsania Hardik; 04.10.2018