DialogFragment 创建对话框

2019-07-17  本文已影响0人  思考者_小徐

前言:

在创建对话框我们通常能想到的是 AlertDialog 和 Dialog 和 PopupWindow, 但是在Android 3.0只有我们引入了
DialogFragment , DialogFragment 是一种特殊的Fragment, Android 官方推荐使用 DialogFragment 来代替 Dialog ,可以让它具有更高的可复用性(降低耦合)和更好的便利性(很好的处理屏幕翻转的情况.

应用

DialogFragment 的创建:

一、 创建 DialogFragment 有两种方式:

  1. 覆写其 onCreateDialog 方法 — ①
  2. 覆写其 onCreateView 方法 — ②

对于方法 ①的创建 创建一个 Dialog 并返回它即可:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    //为了样式统一和兼容性,可以使用 V7 包下的 AlertDialog.Builder
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // 设置主题的构造方法
    // AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomDialog);
    builder.setTitle("注意:")
           .setMessage("是否退出应用?")
           .setPositiveButton("确定", null)
           .setNegativeButton("取消", null)
           .setCancelable(false);
           //builder.show(); // 不能在这里使用 show() 方法
    return builder.create();
}

对于方法二,你也可以使用自定义 View 来创建:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // 设置主题的构造方法
    // AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomDialog);
    LayoutInflater inflater = getActivity().getLayoutInflater();  
    View view = inflater.inflate(R.layout.fragment_dialog, null);  
    builder.setView(view) 
    // Do Someting,eg: TextView tv = view.findViewById(R.id.tv);
    return builder.create();
}

创建 Dialog 的方式有多种,比如下面这种,使用时略有差异,需要自己注意:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = getActivity().getLayoutInflater();
    View view = inflater.inflate(R.layout.fragment_dialog, null);
    Dialog dialog = new Dialog(getActivity());
    // 设置主题的构造方法
    // Dialog dialog = new Dialog(getActivity(), R.style.CustomDialog);
    dialog.setContentView(view);
    // Do Someting
    return dialog;
}

在方法二,基本和Fragment 一样, 不过要注意Fragment的生命周期,另外DialogFragment 默认是有Title 的,注意根据需要设置

Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_dialog, container, false);
    // Do Someting
    return rootView;
}
/**
 * 设置主题需要在 onCreate() 方法中调用 setStyle() 方法
 */
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NO_TITLE, R.style.CustomDialog);
}

常见问题处理

  1. 屏幕旋转问题
    当屏幕旋转时,如果用户未做任何限定,视图中所有的空间和容器多会进行销毁和重新创建,因此当前情况下弹出对话框, 如果屏幕旋转,之前对话框中的内容都会丢失,因此,正常情况都需要处理这个问题,但是现在用DialogFramt 来做对话框, 就可以完全不用考虑这个问题了,FragmentManager 会自动管理 DialogFragment 的生命周期。
  2. 标题栏/全屏
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /**
     * setStyle() 的第一个参数有四个可选值:
     * STYLE_NORMAL|STYLE_NO_TITLE|STYLE_NO_FRAME|STYLE_NO_INPUT
     * 其中 STYLE_NO_TITLE 和 STYLE_NO_FRAME 可以关闭标题栏
     * 每一个参数的详细用途可以直接看 Android 源码的说明
     */
    setStyle(DialogFragment.STYLE_NO_TITLE, R.style.CustomDialog);
}
  1. DialogFragment做屏幕适配
public void showDialogInDifferentScreen(View view)
    {
        FragmentManager fragmentManager = getFragmentManager();
        EditNameDialogFragment newFragment = new EditNameDialogFragment();
 
        boolean mIsLargeLayout = getResources().getBoolean(R.bool.large_layout) ;
        Log.e("TAG", mIsLargeLayout+"");
        if (mIsLargeLayout )
        {
            // The device is using a large layout, so show the fragment as a
            // dialog
            newFragment.show(fragmentManager, "dialog");
        } else
        {
            // The device is smaller, so show the fragment fullscreen
            FragmentTransaction transaction = fragmentManager
                    .beginTransaction();
            // For a little polish, specify a transition animation
            transaction
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            // To make it fullscreen, use the 'content' root view as the
            // container
            // for the fragment, which is always the root view for the activity
            transaction.replace(R.id.id_ly, newFragment)
                    .commit();
        }
    }

效果:

[图片上传失败...(image-94ef89-1563373384992)]
](https://img.haomeiwen.com/i5900919/ddd267269cba6437.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="8dp"/>
    <stroke android:color="#FDFFFFFF"/>
    <solid android:color="#FDFFFFFF"/>
</shape>

DialogFragment 的一些设置

这里我就不做详细介绍, 可以参考
https://blog.csdn.net/angcyo/article/details/50613084

个人总结

  1. 和传统的Dialog相比, Fragment有更多的生命周期,处理复杂的逻辑更有优势,另外不需要处理屏幕旋转问题
  2. 两种方式都能实现相同的效果,但是它们各有自己适合的应用场景:
    方法 ①,一般用于创建替代传统的 Dialog 对话框的场景,UI 简单,功能单一。
    方法 ②,一般用于创建复杂内容弹窗或全屏展示效果的场景,UI 复杂,功能复杂,一般有网络请求等异步操作。

应用场景区别

参考链接

https://likfe.com/2016/10/27/dialog-fragment/
https://blog.csdn.net/angcyo/article/details/50613084
https://blog.csdn.net/lmj623565791/article/details/37815413

上一篇 下一篇

猜你喜欢

热点阅读