我有一个警告对话框,其中包含一个选项列表和两个按钮: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
按钮时获取所选单选按钮的名称。我试图将字符串保存在变量中,但在内部类中,可以只访问最终变量。有没有办法避免使用最终变量来存储选定的单选按钮?
答案 0 :(得分:134)
使用最终变量显然不起作用(因为它只能在声明时分配一次)。所谓的“全局”变量通常是代码气味(特别是当它们成为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();
答案 1 :(得分:15)
这已经得到了很好的解答,但我一直在寻找谷歌的这个答案,我想分享一个非匿名的类解决方案。我自己更喜欢可重复使用的课程,可能对其他人有帮助。
在此示例中,我使用DialogFragment
实现并通过回调方法检索值。
从 Dialog 获取值的回调方法可以通过创建公共界面
来完成public interface OnDialogSelectorListener {
public void onSelectedOption(int selectedIndex);
}
同样DialogFragment
实现DialogInterface.OnClickListener
,这意味着您可以将正在实现的类注册为正在创建的DialogFragment
的 OnClickListener 。 / p>
例如
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);
答案 2 :(得分:9)
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();
答案 3 :(得分:0)
尝试一下。
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();
答案 4 :(得分:0)
正如其他人指出的那样,实现'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();
答案 5 :(得分:0)
Android AlertDialog 可用于通过“确定”和“取消”按钮显示对话框消息。它可以用来打扰并询问用户有关他/她选择继续还是终止的信息。AlertDialog单选项目示例由三个区域组成:标题,内容区域和操作按钮。 Android AlertDialog是Dialog类的子类。 MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val context = this
button.setOnClickListener {
val builder = MaterialAlertDialogBuilder(context)
// dialog title
builder.setTitle("Which is your favorite?")
val colors = arrayOf(
"African violet",
"Alice blue",
"Alloy orange",
"Android green",
"Amaranth pink",
"Antique bronze"
)
// set single choice items
builder.setSingleChoiceItems(
colors, // array
-1 // initial selection (-1 none)
){dialog, i ->}
// alert dialog positive button
builder.setPositiveButton("Submit"){dialog,which->
val position = (dialog as AlertDialog).listView.checkedItemPosition
// if selected, then get item text
if (position !=-1){
val selectedItem = colors[position]
textView.text = "Favorite color : $selectedItem"
}
}
// alert dialog other buttons
builder.setNegativeButton("No",null)
builder.setNeutralButton("Cancel",null)
// set dialog non cancelable
builder.setCancelable(false)
// finally, create the alert dialog and show it
val dialog = builder.create()
dialog.show()
// initially disable the positive button
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
// dialog list item click listener
dialog.listView.onItemClickListener =
OnItemClickListener { parent, view, position, id ->
// enable positive button when user select an item
dialog.getButton(AlertDialog.BUTTON_POSITIVE)
.isEnabled = position != -1
}
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/constraintLayout"
tools:context=".MainActivity">
<com.google.android.material.button.MaterialButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Show Dialog"
android:backgroundTint="#4B5320"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
tools:text="TextView"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>