Как мне создать Android Spinner как всплывающее окно?

Я хочу вызвать диалоговое окно, когда пользователь нажимает на элемент меню, чтобы позволить ему выбрать элемент.

Мне нужен отдельный диалог для этого или я могу использовать Spinner напрямую? Я вижу эту ссылку, упоминает опцию MODE_DIALOG, но она больше не определяется. AlertDialog может быть в порядке, но все опции говорят: "щелчок по элементу в списке не приведет к закрытию диалога", что я и хочу. Любое предложение?

В идеале код должен быть аналогичен случаю, когда на экране отображается счетчик:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity,
     android.R.layout.simple_spinner_item, items);              
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
myspinner.setAdapter(adapter);  
// myspinner.showAsDialog() <-- what i want             

10 ответов

Решение

Вы можете использовать диалоговое окно оповещения

    AlertDialog.Builder b = new Builder(this);
    b.setTitle("Example");
    String[] types = {"By Zip", "By Category"};
    b.setItems(types, new OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {

            dialog.dismiss();
            switch(which){
            case 0:
                onZipRequested();
                break;
            case 1:
                onCategoryRequested();
                break;
            }
        }

    });

    b.show();

Это закроет диалоговое окно, когда один из них нажата, как вы хотите. Надеюсь это поможет!

В xml есть вариант

android:spinnerMode="dialog"

используйте это для режима диалога

Попробуй это:

Spinner popupSpinner = new Spinner(context, Spinner.MODE_DIALOG);

Смотрите эту ссылку для более подробной информации.

MODE_DIALOG и MODE_DROPDOWN определены в API 11 (Сота). MODE_DIALOG описывает обычное поведение в предыдущих версиях платформы.

Добавление небольшого атрибута как android:spinnerMode="dialog" покажет содержимое счетчика во всплывающем окне.

Вы можете создать свой собственный диалог. Это довольно просто. Если вы хотите отклонить его с помощью выделения в счетчике, то добавьте OnItemClickListener и добавить

int n = mSpinner.getSelectedItemPosition();
mReadyListener.ready(n);
SpinnerDialog.this.dismiss();

как в OnClickListener для кнопки ОК. Однако есть одна оговорка, и это то, что слушатель onclick не срабатывает, если вы повторно выберете опцию по умолчанию. Вам также нужна кнопка ОК.

Начнем с макета:

res / layout / spinner_dialog.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content">
<TextView 
    android:id="@+id/dialog_label" 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent"
    android:hint="Please select an option" 
    />
<Spinner
    android:id="@+id/dialog_spinner" 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent"
    />
<Button
    android:id="@+id/dialogOK" 
    android:layout_width="120dp"
    android:layout_height="wrap_content" 
    android:text="OK"
    android:layout_below="@id/dialog_spinner"
    />
<Button
    android:id="@+id/dialogCancel" 
    android:layout_width="120dp"
    android:layout_height="wrap_content" 
    android:text="Cancel"
    android:layout_below="@id/dialog_spinner"
    android:layout_toRightOf="@id/dialogOK"
    />
</RelativeLayout>

Затем создайте класс:

src / your / package / SpinnerDialog.java:

public class SpinnerDialog extends Dialog {
    private ArrayList<String> mList;
    private Context mContext;
    private Spinner mSpinner;

   public interface DialogListener {
        public void ready(int n);
        public void cancelled();
    }

    private DialogListener mReadyListener;

    public SpinnerDialog(Context context, ArrayList<String> list, DialogListener readyListener) {
        super(context);
        mReadyListener = readyListener;
        mContext = context;
        mList = new ArrayList<String>();
        mList = list;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.spinner_dialog);
        mSpinner = (Spinner) findViewById (R.id.dialog_spinner);
        ArrayAdapter<String> adapter = new ArrayAdapter<String> (mContext, android.R.layout.simple_spinner_dropdown_item, mList);
        mSpinner.setAdapter(adapter);

        Button buttonOK = (Button) findViewById(R.id.dialogOK);
        Button buttonCancel = (Button) findViewById(R.id.dialogCancel);
        buttonOK.setOnClickListener(new android.view.View.OnClickListener(){
            public void onClick(View v) {
                int n = mSpinner.getSelectedItemPosition();
                mReadyListener.ready(n);
                SpinnerDialog.this.dismiss();
            }
        });
        buttonCancel.setOnClickListener(new android.view.View.OnClickListener(){
            public void onClick(View v) {
                mReadyListener.cancelled();
                SpinnerDialog.this.dismiss();
            }
        });
    }
}

Наконец, используйте его как:

mSpinnerDialog = new SpinnerDialog(this, mTimers, new SpinnerDialog.DialogListener() {
  public void cancelled() {
    // do your code here
  }
  public void ready(int n) {
    // do your code here
  }
});
android:spinnerMode="dialog"

// Creating adapter for spinner

ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, categories);

// Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);

Вы можете использовать спиннер и установить spinnerMode в диалоговое окно и установить для layout_width и layout_height значение 0, чтобы основной вид не отображал только диалоговое окно (раскрывающийся вид). Вызвать executeClick в слушателе кнопки click.

    mButtonAdd.setOnClickListener(view -> {
        spinnerAddToList.performClick();
    });

Планировка:

    <Spinner
        android:id="@+id/spinnerAddToList"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="10dp"
        android:prompt="@string/select_from_list"
        android:theme="@style/ThemeOverlay.AppCompat.Light"
        android:spinnerMode="dialog"/>

Преимуществом этого является то, что вы можете настроить свой счетчик так, как вы хотите.

Смотрите мой ответ здесь, чтобы настроить спиннер: Переопределение стиля выпадающего списка для Spinner в режиме диалога

Вот подкласс Spinner, который переопределяет executeClick(), чтобы показать диалог вместо выпадающего списка. XML не требуется. Попробуйте, дайте мне знать, если это работает для вас.

public class DialogSpinner extends Spinner {
    public DialogSpinner(Context context) {
        super(context);
    }

    @Override 
    public boolean performClick() {
        new AlertDialog.Builder(getContext()).setAdapter((ListAdapter) getAdapter(), 
            new DialogInterface.OnClickListener() {
                @Override public void onClick(DialogInterface dialog, int which) {
                    setSelection(which);
                    dialog.dismiss();
                }
            }).create().show();
        return true;
    }
}

Для получения дополнительной информации прочитайте эту статью: Как сделать параметры Spinner для Android всплывающими в диалоговом окне

Если вы хотите отображать его как всплывающее окно во весь экран, вам даже не нужен макет xml. Вот как это сделать в Котлине.

 val inputArray: Array<String> = arrayOf("Item 1","Item 2")
                val alt_bld =  AlertDialog.Builder(context);
                alt_bld.setTitle("Items:")
                alt_bld.setSingleChoiceItems(inputArray, -1) { dialog, which ->
                    if(which == 0){
                        //Item 1 Selected
                    }
                    else if(which == 1){
                        //Item 2 Selected
                    }
                    dialog.dismiss();

                }

                val alert11 = alt_bld.create()
                alert11.show()

Вот версия Kotlin, основанная на принятом ответе.

Я использую этот диалог из адаптера каждый раз, когда нажимается кнопка.

yourButton.setOnClickListener {
    showDialog(it /*here I pass additional arguments*/)
}

Чтобы предотвратить двойные щелчки, я немедленно отключаю кнопку и снова включаю после выполнения / отмены действия.

private fun showDialog(view: View /*additional parameters*/) {
    view.isEnabled = false

    val builder = AlertDialog.Builder(context)
    builder.setTitle(R.string.your_dialog_title)

    val options = arrayOf("Option A", "Option B")

    builder.setItems(options) { dialog, which ->
        dialog.dismiss()

        when (which) {
            /* execute here your actions */
            0 -> context.toast("Selected option A")
            1 -> context.toast("Selected option B")
        }

        view.isEnabled = true
    }

    builder.setOnCancelListener {
        view.isEnabled = true
    }

    builder.show()
}

Ты можешь использовать this вместо context переменная, если вы используете ее из Activity.

Это из исходного кода Android SDK. Как видите, у вас есть специальный конструктор для создания Spinner с указанным режимом, который вы хотите использовать.

Надеюсь, это поможет вам:)

 /**
     * Construct a new spinner with the given context's theme, the supplied attribute set,
     * and default style. <code>mode</code> may be one of {@link #MODE_DIALOG} or
     * {@link #MODE_DROPDOWN} and determines how the user will select choices from the spinner.
     *
     * @param context The Context the view is running in, through which it can
     *        access the current theme, resources, etc.
     * @param attrs The attributes of the XML tag that is inflating the view.
     * @param defStyle The default style to apply to this view. If 0, no style
     *        will be applied (beyond what is included in the theme). This may
     *        either be an attribute resource, whose value will be retrieved
     *        from the current theme, or an explicit style resource.
     * @param mode Constant describing how the user will select choices from the spinner.
     * 
     * @see #MODE_DIALOG
     * @see #MODE_DROPDOWN
     */
    public Spinner(Context context, AttributeSet attrs, int defStyle, int mode) {
        super(context, attrs, defStyle);
Другие вопросы по тегам