DialogFragment使用及注意事项

一、DialogFragment基础

参考自谷歌安卓文档

1、实现类继承自DialogFragment类
2、必须重写onCreateViewonCreateDialog方法,onCreateView可以自定义对话框,onCreateDialog使用默认对话框
3、DialogFragment包含Dialog.setOnCancelListener()Dialog.setOnDismissListener()回调,可在取消或清除对话框时自定义操作
4、利用bundlesetArguments()getArguments()方法,实现Fragment或Activity与Dialogfragment间的参数传递

二、DialogFragment使用代码示例

1、自定义DialogFragment类

DataBinding,ViewModel与DialogFragment结合

public class mDialog extends DialogFragment {
    //DialogFragment的构造函数方法体需要为空
    //创建对象写在newInstance方法中
    public static mDialog newInstance(Equipment item) {
        DialogCurtain fragment = new mDialog ();
        Bundle bundle = new Bundle();
        bundle.putSerializable(Equipment.curtain, item);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.item_operate_curtain_motion, container, false);
        binding.setLifecycleOwner(this);
        viewModel = new ViewModelProvider(getActivity()).get(EquipmentViewModel.class);
        Bundle bundle = getArguments();
        if (bundle != null) {
            item = (Equipment) bundle.getSerializable(Equipment.curtain);
        }
        return binding.getRoot();
    }
2、在OnStart()OnResume()回调中对自定义对话框进行显示设置
    @Override
    public void onStart() {
        Dialog dialog = getDialog();
        if (dialog != null) {
            Window window = getDialog().getWindow();
            window.setBackgroundDrawable(new ColorDrawable(Color.BLACK));
            //设置背景透明度
            window.setDimAmount(0.75F);
            DisplayMetrics dm = new DisplayMetrics();
            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
            WindowManager.LayoutParams attributes = dialog.getWindow().getAttributes();
            dialog.getWindow().setAttributes(attributes);
            //自定义对话框显示比例
            dialog.getWindow().setLayout((int) (dm.widthPixels * 0.4), (int) (dm.heightPixels * 0.75));
        }
        super.onStart();
    }
3、Fragment中显示DialogFragment

开启Fragment事务,将DialogFragment加到回退栈中
show()方法进行显示

    private fun showDialog(str: String, item: Equipment) {
        val ft: FragmentTransaction = parentFragmentManager.beginTransaction()
        val prev: Fragment? = getFragmentManager()?.findFragmentByTag("dialog")
        if (prev != null) {
            ft.remove(prev)
        }
        ft.addToBackStack(null)
        val newFragment: mDialog= mDialog.newInstance(item)
        newFragment.show(ft, "dialog")
        }
    }

三、DialogFragment点击背景取消对话框与底部导航栏冲突

产品提出需求如下:
点击对话框布局的关闭按钮和对话框空白处背景,都可以取消对话框。
在开发过程中,发现外部点击事件失效,原因在于

window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

借鉴https://www.jianshu.com/p/6d48fd0ce177
通过这句话屏蔽了底部导航栏,但这个属性使背景区域的点击事件穿透到底层View。
于是进行如下处理:

 dialog.setOnShowListener(v -> {
                dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
                Utils.hideSystemUI(dialog.getWindow().getDecorView());
            });

当对话框显示之后取消当时Flag。
另外通过对dismiss()方法的监听可在对话框消失时进行一些刷新操作

            dialog.setOnDismissListener(v -> {
                Handler handler = new Handler();
                handler.postDelayed(() -> {
                    EventBus.getDefault().post(new EquipmentEvent("Dialog dismiss"));
                }, 500);
            });

你可能感兴趣的:(DialogFragment使用及注意事项)