一. 前言 1 2 3 java.lang.Object ↳android.app.Dialog
那么什么叫Dialog
,简单来说就是一句话:弹出一个窗口,提示用户自己去选择。Dialog
的生命周期通常会由Activity
来控制,当Activity
被销毁后,如果再有对Dialog
的操作会导致异常。
1 java.lang.IllegalArgumentException: View not attached to window manager。
Android系统自带的Dialog
有四种:
-AlertDialog
普通提示对话框,可以有0-3个按钮,可以有单选或者复选框的对话框,可以创建大多数界面
-ProgressDialog
进度条对话框,显示一个进度或者进度条,继承自AlertDialog
-DatePickerDialog
日期对话框
-TimePickerDialog
时间对话框
所有对话框,都是直接或简介继承自Dialog
,其它的几个类均继承自AlertDialog
。
二. 系统默认的弹框 1. 普通的对话框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public void showDialog (View view) { AlertDialog.Builder builder = new AlertDialog.Builder(this ); builder.setTitle("提示标题" ); builder.setMessage("显示的信息" ); builder.setPositiveButton("确定" , new DialogInterface.OnClickListener() { @Override public void onClick (DialogInterface dialog, int which) { } }); builder.setNeutralButton("取消" , new DialogInterface.OnClickListener() { @Override public void onClick (DialogInterface dialog, int which) { dialog.dismiss(); } }); AlertDialog alertDialog = builder.create(); alertDialog.show(); }
2. 菜单按钮样式的对话框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void showMenuDialog (View view) { final String[] messages = { "身高160cm的妹子" , "身高165cm的妹子" , "身高170cm的妹子" , "身高175cm的妹子" }; AlertDialog.Builder builder = new AlertDialog.Builder(this ); builder.setTitle("选择你喜欢的妹子" ); builder.setItems(messages, new DialogInterface.OnClickListener() { @Override public void onClick (DialogInterface dialog, int which) { Toast.makeText(MainActivity.this , "我喜欢" +messages[which], Toast.LENGTH_SHORT).show(); } }); AlertDialog alertDialog = builder.create(); alertDialog.show(); }
3. 单选按钮样式的对话框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void showRadioDialog (View view) { final String[] messages = { "身高160cm的妹子" , "身高165cm的妹子" , "身高170cm的妹子" , "身高175cm的妹子" }; AlertDialog.Builder builder = new AlertDialog.Builder(this ); builder.setTitle("选择你喜欢的妹子" ); builder.setSingleChoiceItems(messages, 0 , new DialogInterface.OnClickListener() { @Override public void onClick (DialogInterface dialog, int which) { Toast.makeText(MainActivity.this , "我喜欢" +messages[which], Toast.LENGTH_SHORT).show(); } }); AlertDialog alertDialog = builder.create(); alertDialog.show(); }
4. 多选按钮样式的对话框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public void showCheckBoxDialog (View view) { final boolean [] checkedItems = {true ,false ,false ,true }; final String[] messages = {"听音乐" ,"看书" ,"睡觉" ,"打豆豆" }; AlertDialog.Builder builder = new AlertDialog.Builder(this ); builder.setTitle("周末你一般都喜欢做什么" ); builder.setMultiChoiceItems(messages, checkedItems, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick (DialogInterface dialog, int which, boolean isChecked) { if (isChecked){ checkedItems[which] = true ; }else { checkedItems[which] = false ; } } }); builder.setPositiveButton("确定" , new DialogInterface.OnClickListener() { @Override public void onClick (DialogInterface dialog, int which) { StringBuilder temp = new StringBuilder(); for (int i = 0 ; i < checkedItems.length; i++) { if (checkedItems[i]){ temp.append(messages[i]+" " ); } } Toast.makeText(MainActivity.this , "我喜欢" +temp, Toast.LENGTH_SHORT).show(); } }); builder.setNegativeButton("取消" ,null ); AlertDialog alertDialog = builder.create(); alertDialog.show(); }
5. 圆形进度样式的对话框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public void showCircleProgressDialog (View view) { ProgressDialog progressDialog = new ProgressDialog(this ); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.setTitle("升级更新" ); progressDialog.setMessage("正在下载..." ); progressDialog.setCancelable(false ); progressDialog.show(); }
6. 水平进度样式的对话框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public void showProgressDialog (View view) { final ProgressDialog progressDialog = new ProgressDialog(this ); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setTitle("升级更新" ); progressDialog.setMessage("正在下载..." ); progressDialog.setCancelable(false ); progressDialog.setMax(100 ); progressDialog.show(); }
7. 选择时间样式的对话框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public void showSelectTimeDialog (View view) { TimePickerDialog timePickerDialog = new TimePickerDialog( this , new TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet (TimePicker view, int hourOfDay, int minute) { Toast.makeText(MainActivity.this , hourOfDay+"时" +minute+"分" , Toast.LENGTH_SHORT).show(); } }, 12 , 12 , true ); timePickerDialog.setTitle("选择你要设定的时间" ); timePickerDialog.show(); }
8. 选择日期样式的对话框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public void showSelectDateDialog (View view) { DatePickerDialog datePickerDialog = new DatePickerDialog( this , new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet (DatePicker view, int year, int month, int dayOfMonth) { Toast.makeText(MainActivity.this , year+"年" +month+"月" +dayOfMonth+"日" , Toast.LENGTH_SHORT).show(); } }, 2019 , 9 , 1 ); datePickerDialog.show(); }
三. 自定义布局的对话框 了解了dialog之后,我们还需要了解一下FragmentDialog,我们常继承它来自定义对话框。
1. 自定义步骤 ① 创建你想要的对话框的布局文件
② 自定义一个继承于DialogFragment的类
③ 在继承的类中重写onCreateDialog,加载布局文件,完成相关的事件处理。
④ 在Activity中使用
2. demo ① 布局文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width ="300dp" android:layout_height ="wrap_content" android:background ="#0000" android:orientation ="vertical" > <RelativeLayout android:layout_width="300dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:background="#fff"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingBottom="20dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="30dp" android:text="开启新世界" android:textSize="18sp" /> <EditText android:id="@+id/login_et1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:background="@null" android:hint="请输入用户名" android:textSize="16sp" /> <View android:layout_width="match_parent" android:layout_height="1px" android:layout_marginTop="5dp" android:background="#d3d3d3" /> <EditText android:id="@+id/login_et2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:background="@null" android:hint="请输入密码" android:inputType="textPassword" android:textSize="16sp" /> <View android:layout_width="match_parent" android:layout_height="1px" android:layout_marginTop="5dp" android:background="#d3d3d3" /> <Button android:id="@+id/login_btn" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="35dp" android:background="#000000" android:padding="5dp" android:text="登 录" android:textColor="#ffffff" android:textSize="16sp" /> </LinearLayout > </RelativeLayout > </LinearLayout >
② 自定义的类以及加载布局处理事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class LoginDialogFragment extends DialogFragment implements View .OnClickListener { private EditText userName; private EditText password; private Button loginBtn; @NonNull @Override public Dialog onCreateDialog (@Nullable Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); View inflate = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_layout, null ); userName = inflate.findViewById(R.id.login_et1); password = inflate.findViewById(R.id.login_et2); loginBtn = inflate.findViewById(R.id.login_btn); loginBtn.setOnClickListener(this ); builder.setView(inflate); return builder.create(); } @Override public void onClick (View v) { switch (v.getId()){ case R.id.login_btn: if (TextUtils.isEmpty(userName.getText().toString()) || TextUtils.isEmpty(password.getText().toString())){ Toast.makeText(getActivity(), "用户名或者密码不能为空" , Toast.LENGTH_SHORT).show(); }else { Toast.makeText(getActivity(), "用户名:" +userName.getText()+"密码:" +password.getText(), Toast.LENGTH_SHORT).show(); } break ; default : break ; } } }
③ 在Activity中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?xml version="1.0" encoding="utf-8" ?> <RelativeLayout 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" tools:context=".MainActivity" > <Button android:id="@+id/login_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点击登录" android:layout_centerInParent="true" /> </RelativeLayout> public class MainActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.login_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { LoginDialogFragment loginDialogFragment = new LoginDialogFragment(); loginDialogFragment.show(getSupportFragmentManager(),"login" ); } }); } }
④ 运行效果
四. 进阶内容 Android 中自定义 Dialog 显示隐藏动画
自定义dialog (构建者模式打造自定义dialog)
参考文章 错误操作怎么办?用他让你不再害怕!—Dialog最详解