AlertDialog按键后不取消对话框实现方式
我们在使用默认Android对话框的上的按键时,当我们按下后,对话框就会自动关闭,但有时某些需求需要我们通过对话框进行与界面进行交互,而不是立即关闭,我们如何实现呢?先看下图吧!
如图Dialog使用了DatePicker和TimePicker,将按键设置日期和时间(2016年9月9日 上午 9点09),这里我设置完日期后还需要提供设置时间,如果把日期和时间弄到一个界面效果不太理想,于是我们通过Dialog上按钮进行切换
实现方法
AlertDialog提供三种positive按钮、negative按钮以及neutral按钮
通过反射将Dialog类中的私有布尔类型成员“mShowing”修改为false
private void canNotCloseDialog(DialogInterface dialogInterface) { try { Class<? extends DialogInterface> aClass = dialogInterface.getClass(); Class<?> superclass = aClass.getSuperclass().getSuperclass(); Field field = superclass.getDeclaredField("mShowing"); field.setAccessible(true); field.set(dialogInterface, false); } catch (Exception e) { e.printStackTrace(); } }
(推荐)通过alertDialog.getButton()方法,拿到按键对象,设置按键侦听
Button btNegative = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE); btNegative.setOnClickListener(new View.OnClickListener() { ... }
分析
这里还存在以下几个问题:
1. 这两种方法有什么区别?为什么推荐第二种?
2. 应该在什么时间使用?
问题1:这两种方法有什么区别?为什么推荐第二种?
- 首先方法1的核心是修改Dialog类中的私有布尔类型成员“mShowing”,谷歌并不提供这个修改该变量的方法,所以有可能在未来谷歌更新过程中,导致反射修改失效。
- 方法1修改后,所有按键(positive按钮、negative按钮以及neutral按钮)点击后均无法关闭对话框,不够灵活。
- 方法2解决了以上两个问题所以推荐
问题2:应该在什么时间使用?
两种方法均只能在dialog显示后才能生效
//在dialog显示侦听进行设置 alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialog) { //在这里处理按键不取消 ... } }
代码
理论说完附上上图的关键代码
dialog_date_picker.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<DatePicker
android:id="@+id/dp_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</DatePicker>
<TimePicker
android:id="@+id/tp_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
/>
</FrameLayout>
dialog关键代码
Date date = new Date();
View view = View.inflate(getActivity(), R.layout.dialog_date_picker, null);
final DatePicker datePicker = (DatePicker) view.findViewById(R.id.dp_dialog);
final TimePicker timePicker = (TimePicker) view.findViewById(R.id.tp_dialog);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
timePicker.setHour(hour);
timePicker.setMinute(minute);
datePicker.init(year, month, day, null);
final AlertDialog alertDialog = new AlertDialog.Builder(getActivity())
.setTitle(R.string.date_picker_title)
.setView(view)
.setNegativeButton(R.string.dialog_to_time, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int year = datePicker.getYear();
int month = datePicker.getMonth();
int day = datePicker.getDayOfMonth();
int hour = timePicker.getHour();
int minute = timePicker.getMinute();
Date date = new GregorianCalendar(year,
month,
day,
hour,
minute).getTime();
sendResult(date);//发送结果
//dialog.dismiss();//如果使用方法1,需要手动关闭dialog
}
})
.create();
alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
//canNotCloseDialog(dialog);//方法1
final Button btNegative = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
btNegative.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isSetData) {
btNegative.setText(R.string.dialog_to_time);
datePicker.setVisibility(View.VISIBLE);
timePicker.setVisibility(View.INVISIBLE);
isSetData = false;
} else {
btNegative.setText(R.string.dialog_to_date);
datePicker.setVisibility(View.INVISIBLE);
timePicker.setVisibility(View.VISIBLE);
isSetData = true;
}
}
});
}
});
alertDialog.setCanceledOnTouchOutside(false);
结束语
如果您觉得这篇文章能够帮助到您,请帮忙顶一下,您的鼓励是对我的最大支持!
如需转载请标明出处。