Подтвердить что ты не робот

Как выбрать запись в AlertDialog с помощью опции checkbox android?

У меня есть диалоговое окно с одним списком и двумя кнопками: кнопка " OK и кнопка " cancel. Код ниже показывает, как я это реализовал.

private final Dialog createListFile(final String[] fileList) {
  AlertDialog.Builder builder = new AlertDialog.Builder(this);
  builder.setTitle("Compare with:");

  builder.setSingleChoiceItems(fileList, -1, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
      Log.d(TAG,"The wrong button was tapped: " + fileList[whichButton]);
    }
  });

  builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {}
  });

  builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {}
  });

  return builder.create();
}

Моя цель - получить имя выбранной радиокнопки при нажатии кнопки OK. Я пытался сохранить строку в переменной, но внутри внутреннего класса можно получить доступ только к конечным переменным. Есть ли способ избежать использования окончательной переменной для сохранения выбранной радиокнопки?

4b9b3361

Ответ 1

Использование конечной переменной, очевидно, не будет работать (поскольку ее можно назначить только один раз, во время объявления). Так называемые "глобальные" переменные обычно представляют собой запах кода (особенно когда они становятся частью класса Activity, который обычно создается при создании AlertDialogs). Чистое решение - передать объект DialogInterface в AlertDialog, а затем вызвать getListView(). GetCheckedItemPosition(). Вот так:

new AlertDialog.Builder(this)
        .setSingleChoiceItems(items, 0, null)
        .setPositiveButton(R.string.ok_button_label, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
                int selectedPosition = ((AlertDialog)dialog).getListView().getCheckedItemPosition();
                // Do something useful withe the position of the selected radio button
            }
        })
        .show();

Ответ 2

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

В этом примере я использую реализацию DialogFragment и получаю значение через метод обратного вызова.

Метод обратного вызова для получения значений из диалогового окна можно сделать, создав общедоступный интерфейс

public interface OnDialogSelectorListener {
    public void onSelectedOption(int selectedIndex);
}

Также DialogFragment реализует DialogInterface.OnClickListener, что означает, что вы можете зарегистрировать класс, который вы реализовали, как OnClickListener для создаваемого DialogFragment.

Например

public Dialog onCreateDialog(Bundle savedInstanceState) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());

    builder.setTitle(R.string.select);
    builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this);
    builder.setPositiveButton(R.string.ok, this);
    builder.setNegativeButton(R.string.cancel, this);
    return builder.create();
}

Линия

builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this);

Создает диалог выбора с параметрами из массива ресурсов, хранящегося в mResourceArray. Это также выбирает индекс опций из того, что хранится в mSelectedIndex, и, наконец, он устанавливает this сам как OnClickListener. (См. Полный код в конце, если этот абзац немного запутан).

Теперь, метод OnClick - это то, где вы берете значение, которое появляется в диалоговом окне

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

    switch (which) {
        case Dialog.BUTTON_NEGATIVE: // Cancel button selected, do nothing
            dialog.cancel();
            break;

        case Dialog.BUTTON_POSITIVE: // OK button selected, send the data back
            dialog.dismiss();
            // message selected value to registered callbacks with the
                    // selected value.
            mDialogSelectorCallback.onSelectedOption(mSelectedIndex);
            break;

        default: // choice item selected
                    // store the new selected value in the static variable
            mSelectedIndex = which;
            break;
    }
}

Что происходит, когда элемент выбран, он хранится в переменной. Если пользователь нажимает кнопку "Отмена", обновление не возвращается и ничего не меняется. Если пользователь нажимает кнопку "ОК", он возвращает значение в Activity, которое создало его с помощью созданного обратного вызова.

В качестве примера, вот как вы создадите диалог из FragmentActivity.

final SelectorDialog sd = SelectorDialog.newInstance(R.array.selector_array, preSelectedValue);
sd.show(getSupportFragmentManager(), TAG);

Здесь массив ресурсов _R.array.selector_array_ - это массив строк для отображения в диалоговом окне, а preSelectedValue - это индекс, который нужно выбрать при открытии.

Наконец, ваш FragmentActivity будет реализовывать OnDialogSelectorListener и получит сообщение обратного вызова.

public class MyActivity extends FragmentActivity implements OnDialogSelectorListener {
// ....

    public void onSelectedOption(int selectedIndex) {
        // do something with the newly selected index
    }
}

Надеюсь, это полезно кому-то, так как мне потребовалось много попыток понять это. Полная реализация этого типа DialogFragment с обратным вызовом здесь.

public class SelectorDialog extends DialogFragment implements OnClickListener {
    static final String TAG = "SelectorDialog";

    static int mResourceArray;
    static int mSelectedIndex;
    static OnDialogSelectorListener mDialogSelectorCallback;

    public interface OnDialogSelectorListener {
        public void onSelectedOption(int dialogId);
    }

    public static DialogSelectorDialog newInstance(int res, int selected) {
        final DialogSelectorDialog dialog  = new DialogSelectorDialog();
        mResourceArray = res;
        mSelectedIndex = selected;

        return dialog;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        try {
            mDialogSelectorCallback = (OnDialogSelectorListener)activity;
        } catch (final ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnDialogSelectorListener");
        }
    }

    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());

        builder.setTitle(R.string.select);
        builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this);
        builder.setPositiveButton(R.string.ok, this);
        builder.setNegativeButton(R.string.cancel, this);
        return builder.create();
    }

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

        switch (which) {
            case Dialog.BUTTON_NEGATIVE:
                dialog.cancel();
                break;

            case Dialog.BUTTON_POSITIVE:
                dialog.dismiss();
                // message selected value to registered calbacks
                mDialogSelectorCallback.onSelectedOption(mSelectedIndex);
                break;

            default: // choice selected click
                mSelectedIndex = which;
                break;
        }

    }
}

Вопрос из комментария Как назвать это из Fragment вместо Activity.

Сначала сделайте несколько изменений в DialogFragment.

Удалите событие onAttach, поскольку это не самый простой способ в этом сценарии.

Добавить новый метод для добавления ссылки на обратный вызов

public void setDialogSelectorListener (OnDialogSelectorListener listener) {
    this.mListener = listener;
}

Внедрите слушателя в Fragment

public class MyFragment extends Fragment implements SelectorDialog.OnDialogSelectorListener {
// ....

    public void onSelectedOption(int selectedIndex) {
        // do something with the newly selected index
    }
}

Теперь создайте новый экземпляр и передайте ссылку на Fragment, чтобы использовать его.

final SelectorDialog sd = SelectorDialog.newInstance(R.array.selector_array, preSelectedValue);
// this is a reference to MyFragment
sd.setDialogSelectorListener(this);
// mActivity is just a reference to the activity attached to MyFragment
sd.show(this.mActivity.getSupportFragmentManager(), TAG);

Ответ 3

final CharSequence[] choice = {"Choose from Gallery","Capture a photo"};

int from; //This must be declared as global !

AlertDialog.Builder alert = new AlertDialog.Builder(activity);
alert.setTitle("Upload Photo");
alert.setSingleChoiceItems(choice, -1, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (choice[which] == "Choose from Gallery") {
            from = 1;
        } else if (choice[which] == "Capture a photo") {
            from = 2;
        }
    }
});
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (from == 0) {
            Toast.makeText(activity, "Select One Choice", 
                        Toast.LENGTH_SHORT).show();
        } else if (from == 1) {
            // Your Code
        } else if (from == 2) {
            // Your Code
        }
    }
});
alert.show();

Ответ 4

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

final String[] fonts = {"Small", "Medium", "Large", "Huge"};

AlertDialog.Builder builder = new AlertDialog.Builder(TopicDetails.this);
builder.setTitle("Select a text size");
builder.setItems(fonts, new DialogInterface.OnClickListener() {
  @Override
  public void onClick(DialogInterface dialog, int which) {
    if ("Small".equals(fonts[which])) {
      Toast.makeText(MainActivity.this,"you nailed it", Toast.LENGTH_SHORT).show();
    }
    else if ("Medium".equals(fonts[which])) {
      Toast.makeText(MainActivity.this,"you cracked it", Toast.LENGTH_SHORT).show();
    }
    else if ("Large".equals(fonts[which])){
      Toast.makeText(MainActivity.this,"you hacked it", Toast.LENGTH_SHORT).show();
    }
    else if ("Huge".equals(fonts[which])){
     Toast.makeText(MainActivity.this,"you digged it", Toast.LENGTH_SHORT).show();
    }
  // the user clicked on colors[which]
  }
});
builder.show();

Ответ 5

Как отмечали другие, реализация 'com.google.android.material: material: 1.0.0' проще

Обратитесь к этому руководству для получения дополнительной информации. https://material.io/develop/android/docs/getting-started/

CharSequence[] choices = {"Choice1", "Choice2", "Choice3"};
boolean[] choicesInitial = {false, true, false};
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(getContext())
    .setTitle(title)
    .setPositiveButton("Accept", null)
    .setNeutralButton("Cancel", null)
    .setMultiChoiceItems(choices, choicesInitial, new DialogInterface.OnMultiChoiceClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which, boolean isChecked) {

      }
    });
alertDialogBuilder.show();

enter image description here