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, чтобы закрыть его. "Открытая" часть a Spinner Это AlertDialog на Android 1.x и 2.x, и я не совсем уверен, как он реализуется на Honeycomb при использовании голографической темы.

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

помимо этого, я бы подумал, что вы хотите бедный UX. Если пользователь открыл 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.

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

первый шаг-создать пользовательский счетчик, расширив класс Spinner. Допустим, я создал класс CustomSpinner в пакете com.БЦ.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" />

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

    @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().


  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фон, чтобы быть вашим кадром анимации drawable.

затем вы можете легко сделать что-то такой начать и остановить его.


Как насчет клонирования нажатия клавиши "Назад"?

хорошо, я просто попробовал

[current activity].dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_BACK));

и он не сделал ничего, что я мог видеть,затем нажал физическую клавишу "Назад", и падение исчезло. Также попытался сделать ACTION_UP сразу после down-никакого эффекта.


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

как насчет setPressed (false)?
Ссылка на сайт: закрыть выпадающий список блесны, когда два из всех в groupview нажаты одновременно

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

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


использовать clearFocus() чтобы закрыть программу spinner

spinner.clearFocus();