DialogFragment是Android3.0之后引入的一种特殊的Fragment,官方建议使用DialogFragment代替Dialog或者AllertDialog来实现弹框的功能,因为它可以更好的管理Dialog的生命周期以及可以更好复用。
使用DialogFragment至少需要实现onCreateView或者onCreateDialog方法。 onCreateView是使用定义的xml布局文件展示Dialog。onCreateDialog是利用AlertDialog或者Dialog创建出Dialog。不过google不推荐直接使用Dialog,我们就使用AlertDialog来创建。
1.实现onCreateView()方法,实现dialog
a.修改dialog的左右边距,使用window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));去除默认边距
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { Dialog dialog = getDialog(); Window window = dialog.getWindow(); if (window != null) { //去除系统自带的margin window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); //设置dialog在界面中的属性 window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT); } }b.系统的返回键或点击dialog旁边的位置,dialog都不消失
//点击旁边位置,dialog不消失 dialog.setCanceledOnTouchOutside(false); //按系统返回键,dialog不消失 dialog.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { return keyCode == KeyEvent.KEYCODE_BACK; } });c.DialogFragment和Activity/Fragment通信:使用监听
permission_dialog_shape.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#fff"/> <corners android:radius="14dp"/> </shape> <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:tools="http://schemas.android.com/tools"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" android:background="@drawable/permission_dialog_shape"> <TextView android:id="@+id/title" android:layout_height="wrap_content" android:layout_marginTop="19dp" android:layout_width="match_parent" android:textSize="17sp" tools:text="@string/yes_to_delete_account" android:textStyle="bold" android:layout_centerHorizontal="true" android:textColor="#333" android:gravity="center"/> <TextView android:id="@+id/content" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_below="@id/title" android:layout_centerHorizontal="true" android:textSize="12sp" android:layout_marginTop="9dp" android:layout_marginBottom="14dp" tools:text="@string/cancellation_hint" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" android:textColor="#666" android:gravity="center"/> <View android:id="@+id/content_bottom_line" android:layout_width="match_parent" android:layout_height="0.5dp" android:layout_below="@id/content" android:background="#eee" /> <LinearLayout android:layout_width="match_parent" android:layout_height="43dp" android:layout_below="@id/content_bottom_line" android:layout_centerHorizontal="true"> <Button android:id="@+id/btn_no" android:layout_height="match_parent" android:layout_width="0dp" android:layout_weight="1" android:background="@null" android:text="@string/string_cancel" android:textAllCaps="false" android:textSize="17sp" android:textColor="#666"/> <View android:id="@+id/vertical_line" android:layout_width="0.5dp" android:layout_height="match_parent" android:background="#eee" /> <Button android:id="@+id/btn_set" android:layout_width="0dp" android:layout_height="43dp" android:text="@string/string_set" android:textSize="17sp" android:textAllCaps="false" android:background="@null" android:textColor="#2283E2" android:layout_weight="1"/> </LinearLayout> </RelativeLayout> </FrameLayout> public class PermissionDialog extends DialogFragment { private String mTitle, mContent; public static PermissionDialog newInstance(String title, String content){ PermissionDialog instance = new PermissionDialog(); Bundle bundle = new Bundle(); bundle.putString(Const.PERMISSION_DIALOG_TITLE, title); bundle.putString(Const.PERMISSION_DIALOG_CONTENT, content); instance.setArguments(bundle); return instance; } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_permission_dialog, container, false); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { Dialog dialog = getDialog(); //去掉默认对话框的标题 dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); Window window = dialog.getWindow(); if (window != null) { //去除系统自带的margin window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); //设置dialog在界面中的属性 window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT); } //点击旁边位置,dialog不消失 dialog.setCanceledOnTouchOutside(false); //按系统返回键,dialog不消失 dialog.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { return keyCode == KeyEvent.KEYCODE_BACK; } }); Bundle bundle = getArguments(); if (null != bundle){ mTitle = bundle.getString(Const.PERMISSION_DIALOG_TITLE); mContent = bundle.getString(Const.PERMISSION_DIALOG_CONTENT); } TextView tvTitle = view.findViewById(R.id.title); TextView tvContent = view.findViewById(R.id.content); Button btnNo = view.findViewById(R.id.btn_no); Button btnSet = view.findViewById(R.id.btn_set); tvTitle.setText(mTitle); tvContent.setText(mContent); btnNo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); if (null != mListener){ mListener.leftClick(); } } }); btnSet.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); if (null != mListener){ mListener.rightClick(); } } }); } public interface OnDialogClickListener{ void leftClick(); void rightClick(); } private OnDialogClickListener mListener; public void setOnDialogClickListener(OnDialogClickListener l){ mListener = l; } }d.屏幕旋转后,监听失效
在Activity/Fragment的onCreate()方法中,通过 FragmentManager 找到重新实例化的 DialogFragment,重新设置一次 Listener
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (null != savedInstanceState && null != getFragmentManager()){ Log.d(TAG, "onCreate: lym333"); PermissionDialog dialog = (PermissionDialog)getFragmentManager().findFragmentByTag("permission"); dialog.setOnDialogClickListener(mListener); } } private void showDialog(){ PermissionDialog dialog = PermissionDialog.newInstance( getString(R.string.location_per_close_title), getString(R.string.location_per_close_content)); assert getFragmentManager() != null; dialog.show(getFragmentManager(), "permission"); dialog.setOnDialogClickListener(mListener); } private PermissionDialog.OnDialogClickListener mListener = new PermissionDialog.OnDialogClickListener() { @Override public void leftClick() {} @Override public void rightClick() { goSystemRight(); } };2.onCreateDialog的方式创建dialog
@NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { View view = LayoutInflater.from(mContext).inflate(R.layout.fragment_permission_dialog, null); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setView(view) .setPositiveButton("set", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) {} }) .setNegativeButton("cancel", null); return builder.create(); }参考:
Android 官方推荐 : DialogFragment 创建对话框
DialogFragment的Listener在屏幕旋转后被重置的问题
DialogFragment使用小结
Android Dialog 设置Margin方式总结