Android对话框Dialog和DialogFragment

概述

我们在app中弹出对话框的时候我们一般会采用Dialog或者是PopWindow,但是自从Android3.0以后google推出了DialogFragment,它可以满足我们弹窗的需求,而且google也推荐弹窗使用DialogFragment。现在我们来看一下官方给出的DialogFragment的解释吧。

A fragment that displays a dialog window, floating on top of its activity’s window. This fragment contains a Dialog object, which it displays as appropriate based on the fragment’s state. Control of the dialog (deciding when to show, hide, dismiss it) should be done through the API here, not with direct calls on the dialog.
Implementations should override this class and implement onCreateView(LayoutInflater, ViewGroup, Bundle) to supply the content of the dialog. Alternatively, they can override onCreateDialog(Bundle) to create an entirely custom dialog, such as an AlertDialog, with its own content.

这段话的意思是:通过一个Fragment展示成一个悬浮在activity上面的弹窗。这个弹窗包含Dialog属性,能够通过Fragment的状态来展示。我们需要通过API来控制这个弹窗的显示、显示位置、消失等。我们自定义实现DialogFragment,必须要实现onCreateView(LayoutInflater, ViewGroup, Bundle) 这个方法,我们可选重载onCreateDialog(Bundle)这个方法,这样我们就可以像操作平常 的Dialog一样去操作了。

对比

为什么google会推荐使用DialogFragment呢?它有什么优点呢?现在我们就简单的来对比一下吧。
DialogFragment是一个Fragment,它有Fragment一样的生命周期,我们可以更好的利用Fragment的周期来控制弹窗,这样我们使用弹窗是不是又更加的灵活了呢。现在屏幕上有弹窗,当我们横竖屏时,而且没有配置configChanges时,Activity会销毁重建,如果我们不在Activity中对Dialog做处理的话,这个时候Dialog消失不会重建,而且还会报Android..has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView。如果是DialogFragment,我们就不用担心了,FragmentManager会帮我们处理弹窗的重建,是不是很好用了。

Demo

这里就不讲Dialog的使用了,做得太多了,如果还有不会的,可以参考Dialog
现在我们就讲DialogFragment的使用。
方式一:
采用我们以前的做法就是在DialogFragment的构造函数中参入我们需要的数据。

    /**
     * 判断的Dialog的构造
     *
     * @param title    Dialog的标题
     * @param content  Dialog的提示内容
     * @param listener Dialog点击的回调
     */
    @SuppressLint("ValidFragment")
    public CommonUseDialogFragment(String title, String content, DialogOnClickListener listener) {
        this.mTitle = title;
        this.mContent = content;
        this.mListener = listener;
        mIsJudgeDialog = true;
        //设置没有Title 兼容低版本
        //this.setStyle(STYLE_NO_TITLE, R.style.TestStyle);
        //设置外部点击不可取消
        this.setCancelable(false);
    }

    /**
     * 选择的Dialog的构造
     *
     * @param title         Dialog的标题
     * @param list          Dialog的选择内容
     * @param listener      Dialog点击的回调
     * @param checkPosition Dialog中上次选中的选项
     */
    @SuppressLint("ValidFragment")
    public CommonUseDialogFragment(String title, List<String> list, DialogOnClickListener listener, int checkPosition) {
        this.mTitle = title;
        this.mList = list;
        this.mListener = listener;
        this.mLastCheckedPosition = checkPosition;
        mIsJudgeDialog = false;
        //设置没有Title 兼容低版本
        //this.setStyle(STYLE_NO_TITLE, R.style.DialogStyle);
        //设置外部点击不可取消
        this.setCancelable(false);
    }
这里的设置DialogFragment的Style,是设置弹窗没有Title和显示风格,如果不这样设置,弹窗可能会有黑色的边框,弹窗设置的Style可以有多种,自己也可以根据自己需要来自定义自己需要的风格,下个给出的是官方文档给的,可以参考看一下。
int style = DialogFragment.STYLE_NORMAL, theme = 0;
        switch ((mNum-1)%6) {
            case 1: style = DialogFragment.STYLE_NO_TITLE; break;
            case 2: style = DialogFragment.STYLE_NO_FRAME; break;
            case 3: style = DialogFragment.STYLE_NO_INPUT; break;
            case 4: style = DialogFragment.STYLE_NORMAL; break;
            case 5: style = DialogFragment.STYLE_NORMAL; break;
            case 6: style = DialogFragment.STYLE_NO_TITLE; break;
            case 7: style = DialogFragment.STYLE_NO_FRAME; break;
            case 8: style = DialogFragment.STYLE_NORMAL; break;
        }
        switch ((mNum-1)%6) {
            case 4: theme = android.R.style.Theme_Holo; break;
            case 5: theme = android.R.style.Theme_Holo_Light_Dialog; break;
            case 6: theme = android.R.style.Theme_Holo_Light; break;
            case 7: theme = android.R.style.Theme_Holo_Light_Panel; break;
            case 8: theme = android.R.style.Theme_Holo_Light; break;
        }
        setStyle(style, theme);

官方推荐的传入弹窗的数据,是采用Fragment的传数据的方法来弄的,我们看一下吧。

    public static VIPDialog newInstance(int descResID, boolean isSubscribe, int gold,
                                        DialogOnClickListener listener, int skuType, int skuId) {
        VIPDialog f = new VIPDialog();
        Bundle b = new Bundle();
        b.putInt(DESC_RES_ID, descResID);
        b.putBoolean(IS_SUBSCRIBE, isSubscribe);
        b.putInt(UNLOCK_GOLD, gold);
        b.putSerializable(UNLOCK_LISTENER, listener);
        b.putInt(SKU_TYPE, skuType);
        b.putInt(SKU_ID, skuId);
        f.setArguments(b);
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if (args != null) {
            mDescResID = args.getInt(DESC_RES_ID, R.string.vip_rights_gallery);
            mIsSubscribe = args.getBoolean(IS_SUBSCRIBE, false);
            mGold = args.getInt(UNLOCK_GOLD, 1);
            mListener = (DialogOnClickListener) args.getSerializable(UNLOCK_LISTENER);
            mSkuType = args.getInt(SKU_TYPE);
            mSkuId = args.getInt(SKU_ID);
        }
    }

大家一看就知道了吧,就是采用Bundle机制来实现的,这样的话是不是很简单了,我们要什么数据,就传什么数据,扩展也是方便了很多。

总结

大家看了之后是不是发现DialogFragment是不是也挺简单的呢,如果有机会,可以用在你的项目中,这样我们不就是那个只会用Dialog的人了,大家试一试吧。如有兴趣可以看下官方的DialogFragment
DialogFragment

文档若有错误,欢迎指正,谢谢!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值