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);
結束語
如果您覺得這篇文章能夠幫助到您,請幫忙頂一下,您的鼓勵是對我的最大支援!
如需轉載請标明出處。