根據官網的解說,對話方塊是一個小型視窗,可提示使用者做出決定或輸入其他資訊。對話方塊不佔滿整個畫面,通常用於提示使用者必須回應才能繼續操作
而Dialog 類別是對話方塊的基礎類別,底下又有多種子類別
Ps.其實原先還有一個子類別叫做ProgressDialog,是 Android 中用來顯示載入中畫面的元件,但在API 26之後已被標記為Deprecated(不建議使用),如需要顯示進度條的對話框歡迎參考之前寫的ProgressBar解說
最基礎的對話方塊,會顯示標題、內文和按鈕(最多三個),也可選取項目清單或自訂版面配置。
首先要先建立一個AlertDialog
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
然後我們就可以開始進行版面配置,例如設置一個小icon
dialog.setIcon(android.R.drawable.ic_dialog_info);//設置圖示(系統預設)
dialog.setIcon(R.drawable.my_icon);//設置圖示(自訂)
設置標題跟內文
dialog.setTitle("標題");
dialog.setMessage("內文");
設置按鈕和點擊事件。注意:兩個按鈕時,左側按鈕用 setNegativeButton
//設置左邊按鈕(NegativeButton)和點擊事件
dialog.setNegativeButton("關閉", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// TODO: ...
}
});
//設置右邊按鈕(PositiveButton)和點擊事件
dialog.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// TODO: ...
}
});
如果想設置3顆按鈕的AlertDialog,在設置按鈕時會跟兩顆按鈕時有所不同
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("普通對話框(3顆按鈕)");
dialog.setMessage("這是內文");
dialog.setIcon(android.R.drawable.ic_dialog_info);
//設置左邊按鈕和點擊事件,按鈕為3時左邊用NeutralButton
dialog.setNeutralButton("關閉", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//TODO: ...
}
});
//設置中間按鈕和點擊事件,按鈕為3時中間按鈕用NegativeButton
dialog.setNegativeButton("按鈕2", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//TODO: ...
}
});
dialog.setPositiveButton("按鈕3", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//TODO: ...
}
});
寫完記得加上dialog.show()才能顯示Dialog
除了按鈕以外,AlertDialog也可用來選取項目清單,分為直接點選、可變更選項和多選三種
//列表內容
String[] items = {"Item1", "Item2", "Item3", "Item4"};
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("列表對話框Dialog");
// 設置item點擊事件處理
dialog.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(MainActivity.this, "你點擊了" + items[i], Toast.LENGTH_SHORT).show();
}
});
dialog.show(); // 顯示dialog
choice = 1; //預設選擇Item2(從0開始)
String[] items = {"Item1", "Item2", "Item3", "Item4"};
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
// 參數1:設置選項List; 參數2:設置預設選中項
dialog.setSingleChoiceItems(items, choice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
choice = i;//紀錄使用者點選的選項之索引值
}
});
dialog.setPositiveButton("單選對話框", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(MainActivity.this, "你選了" + items[choice], Toast.LENGTH_SHORT).show();
}
});
dialog.show(); // 顯示dialog
String[] items = {"Item1", "Item2", "Item3", "Item4"};
// 設置默認選中項, false表示未選中, true反之
boolean choiceSets[] = {false, true, false, false};
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("多選對話框");
dialog.setMultiChoiceItems(items, choiceSets,
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i, boolean b) {
choiceSets[i] = b;//紀錄使用者點選的選項之索引值,加入陣列
}
}
);
dialog.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String result = "";
//把陣列裡的索引值一個一個抓出來顯示
for (int k = 0; k < items.length; k++) {
if (choiceSets[k]) {
result += items[k] + "\\";
}
}
Toast.makeText(MainActivity.this, "你選中了" + result, Toast.LENGTH_SHORT).show();
}
});
dialog.show(); // 顯示dialog
如果你不喜歡預設的這些對話方塊,也可以使用自訂的版面配置,根據預設,自訂版面配置會填滿對話方塊視窗,但你可以用AlertDialog.Builder來新增按鈕和標題,請記住,若是想自訂版面配置,必須新建一個專門的xml檔,並在xml檔中將其設為顯示為對話方塊,如下
<activity android:theme="@android:style/Theme.Holo.Dialog" >
範例程式碼:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// 取得 LayoutInflater 物件
//將 XML 版面檔 (R.layout.dialog_signin) 轉換成View
LayoutInflater inflater = requireActivity().getLayoutInflater();
// 設置自訂的對話框版面
builder.setView(inflater.inflate(R.layout.dialog_signin, null))
// 設置按鈕與點擊事件
builder.setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// 使用者點擊「登入」後的處理
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// 使用者點擊「取消」時,關閉對話框
LoginDialogFragment.this.getDialog().cancel();
}
});
// 回傳建立好的 AlertDialog 實體
return builder.create();
1.dialog.create().show()
手動先建立 AlertDialog 實體,再顯示,如你要變更按鈕樣式、延遲顯示、或加入 EditText 等,就建議用 create()。如果只是單純顯示訊息則直接用 show() 即可。
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title").setMessage("Message");
AlertDialog alert = builder.create(); // 手動建立
alert.show();
// 之後可以控制按鈕
alert.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.RED);
dialog.setCancelable(true); // 點擊對話框以外可取消顯示
dialog.setCancelable(false); // 必須按按鈕才能關閉
要注意的是在Android(Java)的Calendar和DatePicker中,月份從0開始計數而不是從1開始,所以如果想讓它顯示出來的是正確的月份記得+1
Calendar calendar = Calendar.getInstance();
DatePickerDialog dialog = new DatePickerDialog(MainActivity.this, new DatePickerDialog.OnDateSetListener() {
// 當日期選擇完畢並按下"OK"按鈕 的事件觸發處理
@Override
public void onDateSet(DatePicker datePicker, int y, int m, int d) {
StringBuilder result = new StringBuilder();
//m+1:在Android(Java)的Calendar和DatePicker中,月份從0開始計數而不是從1開始。
result.append(y).append("-").append(m+1).append("-").append(d);
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}
},calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
//取出當前年月日作為預設選項
dialog.show();
可限制只能選今天之後的日期(如生日不能選未來)
dialog.getDatePicker().setMinDate(System.currentTimeMillis());
限制只能選特定區間
// 限制最早日期為 2020/01/01
Calendar minDate = Calendar.getInstance();
minDate.set(2020, 0, 1); // 月份一樣是從 0 開始
// 限制最晚日期為 2025/12/31
Calendar maxDate = Calendar.getInstance();
maxDate.set(2025, 11, 31); // 12 月是 11
dialog.getDatePicker().setMinDate(minDate.getTimeInMillis());
dialog.getDatePicker().setMaxDate(maxDate.getTimeInMillis());
TimePicker有兩種顯示樣式,圓盤或是滾輪式,可以在程式碼中自訂
Calendar calendar = Calendar.getInstance();
//TimePicker 時間選擇器
//android.R.style.Theme_Holo_Light_Dialog_NoActionBar 顯示樣式(Spinner(滾輪))
//android.R.style.Theme_DeviceDefault_Light_Dialog 顯示樣式(圓形時鐘)
TimePickerDialog dialog = new TimePickerDialog(MainActivity.this, android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
new TimePickerDialog.OnTimeSetListener() {
// 當時間選擇完畢並按下"OK"按鈕 的事件觸發處理
@Override
public void onTimeSet(TimePicker timePicker, int h, int m) {
StringBuilder result = new StringBuilder();
//格式化時間並補零
String timeStr = String.format("%02d:%02d", h, m);
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}
}, calendar.get(Calendar.HOUR_OF_DAY), // 24小時制的時
calendar.get(Calendar.MINUTE),// 分
true);// 是否使用24小時制,true = 24小時制,false = 12小時制
//取出當前時間作為預設選項
dialog.show();
以下是這篇文章用到元件所需要的import
// 📅 日期與時間用
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.widget.DatePicker;
import android.widget.TimePicker;
// 🎲 其他功能
import java.util.Random; // 用於亂數生成
// 📦 Dialog 相關
import android.content.DialogInterface;
import androidx.appcompat.app.AlertDialog;
// 🍞 UI 提示
import android.widget.Toast;
import java.util.Random;//亂數計算 非Dialog
import android.content.DialogInterface;
import java.util.Timer;
import java.util.TimerTask;
import android.app.DatePickerDialog;
import android.widget.DatePicker;
import java.util.Calendar;
import android.app.TimePickerDialog;
import android.widget.TimePicker;