美文网首页android学习
DialogFragment使用及注意事项

DialogFragment使用及注意事项

作者: 田田ww | 来源:发表于2021-01-04 18:18 被阅读0次

    一、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使用及注意事项

        本文链接:https://www.haomeiwen.com/subject/ofvvoktx.html