На этот вопрос получен хороший ответ, но я продолжаю находить этот ответ в Google и хочу поделиться неанонимным решением для класса. Я сам предпочитаю многоразовые занятия и могу быть полезен другим.
В этом примере я использую реализацию DialogFragment
и извлекаю значение с помощью метода callback .
Метод callback для получения значений из Диалога может быть выполнен путем создания общедоступного интерфейса
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
, которое его создало, с помощью callback .
В качестве примера, вот как вы могли бы создать диалог из 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);