官方推荐的Dialog——DialogFragment

简介

官方推荐使用的Dialog类型,继承自Fragment,通过FragmentManager管理对话弹框。由于继承自Fragment,使用dialog时完全可以将其看作Fragment。
使用DialogFragment需要实现onCreateView()、onCreateDialog()其中之一
onCreateView即将完全自定义一个dialog。
onCreateDialog即重用Dialog样式,仅用此管理dialog。

好处:
1. 旋转屏幕、按下后退键时 等情况可以更好的管理其声明周期。
2. 提供方法将Dialog作为内嵌的组件进行重用

实现
就将其完全当作一个Fragment来使用就OK了,这里就不贴代码了。。。

注意点

1.去掉dialog的title

在onCreateView方法中添加getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        View inflate = inflater.inflate(R.layout.dialog_picture_verfy, container);
        ButterKnife.inject(this, inflate);
        return inflate;
    }

2.Activity传参到Dialog

使用Fragment的传参方式

    public static PictureVerfyDialog newInstance(FaFaIMMessageModel fafaModel) {
        Bundle args = new Bundle();
        args.putSerializable(PARAM_FAFA_MESSAGE, fafaModel);
        PictureVerfyDialog fragment = new PictureVerfyDialog();
        fragment.setArguments(args);
        return fragment;
    }

3.物理返回键不消失

onCreate()方法中调用:

this.setCancelable(false);

onCreateDialog方式:

点击外部不消失的方法:getDialog.setCanceledOnTouchOutside(false);

对于点击返回键不消失,需要监听OnKeyListener:

getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    return true;
                }
                return false;
            }
        });

4.传递数据给Activity

类似fragment,通过Interface外抛的方式传递数据

    /**
     * 1. 创建监听接口
     *
     * @author fengzhen
     * @version v5.2.4, 2017/6/22 18:36
     */
    public interface OnDismissListener {
        void onDismiss();
    }

    // 2. 内部属性
    private OnDismissListener mOnDismissListener;

    /**
     * 3. 设置监听接口, activity中调用此方法进行设置
     *
     * @author fengzhen
     * @version v5.2.4, 2017/6/22 18:38
     */
    public void setmOnDismissListener(OnDismissListener mOnDismissListener) {
        this.mOnDismissListener = mOnDismissListener;
    }

    // 4. 具体的使用,调用activity中的接口的具体实现方法
    public void onDismiss() {
        if (mOnDismissListener != null){
            mOnDismissListener.onDismiss();
        }
    }

5.抛出异常:IllegalStateException

调用show()方法抛出此异常
IllegalStateException: Can not perform this action after onSaveInstanceState

解决方式:
官方提供了方法:

    /** {@hide} */
    public void showAllowingStateLoss(FragmentManager manager, String tag) {
        mDismissed = false;
        mShownByMe = true;
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commitAllowingStateLoss();
    }

但是很心机的hide了,这里通过反射的方式,强行执行这个方法的内容。

    /**
     * 使用反射重写showAllowingStateLoss()方法
     * 解决调用show()方法异常
     *
     * @author fengzhen
     * @version v5.2.4, 2017/7/2 17:29
     */
    public void showAllowingStateLoss(FragmentManager manager, String tag) {
        try {
            Field mDismissed = DialogFragment.class.getDeclaredField("mDismissed");
            mDismissed.setAccessible(true);
            mDismissed.set(this,false);
            Field mShownByMe = DialogFragment.class.getDeclaredField("mShownByMe");
            mShownByMe.setAccessible(true);
            mShownByMe.set(this,true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commitAllowingStateLoss();
    }

注意不能直接把@hide的方法反射出来调用,所以下面的方法抛出异常 NosuchMethodException:

    public void showAllowingStateLoss(FragmentManager manager, String tag) {
        try {
            Method showAllowingStateLoss = DialogFragment.class.getDeclaredMethod("showAllowingStateLoss", FragmentManager.class, String.class);
            showAllowingStateLoss.setAccessible(true);
            showAllowingStateLoss.invoke(this, manager, tag);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

补充

1. 反射中:getDeclaredMethod()、getMethod区别

getDeclaredMethod():类自身声明的所有方法
getMethod():获取的是public方法

2.反射中:private的属性

赋值之前setAccessible(true),设定为可以修改。
发布了82 篇原创文章 · 获赞 69 · 访问量 14万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章