关于DialogFragment的一些学习

关于DialogFragment的一些学习

标签(空格分隔): DialogFrgment


经历了一个月的项目期,Google给我的最好礼物莫过于谷歌官方网站了
点击进入Google官网DialogFragment介绍

自从Fragment时代的到来,任何View都可以封装到一个Fragment中,然后代替原来的固定的布局模式;DialogFragment因为继承于Fragment并封装了一个Dialog, 所以,有两种方式可以启动DialogFragment.

调用DialogFragment的show()方法,覆盖模式

void showDialog() {
    // Create the fragment and show it as a dialog.
    DialogFragment newFragment = MyDialogFragment.newInstance();
    newFragment.show(getFragmentManager(), "dialog");
}

show方法的实现

    public void show(FragmentManager manager, String tag) {
        mDismissed = false;
        mShownByMe = true;
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commit();
    }

按照Fragment的加载方式,加载到内容区域

FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = MyDialogFragment.newInstance();
ft.add(R.id.embedded, newFragment);
ft.commit();

在Dialog的构造方法中,实例化了一个属于自己的Window对象,这个很重要。

 Dialog(Context context, int theme, boolean createContextThemeWrapper) {
  ····
        mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        Window w = PolicyManager.makeNewWindow(mContext);
        mWindow = w;
        w.setCallback(this);
        w.setOnWindowDismissedCallback(this);
        w.setWindowManager(mWindowManager, null, null);
        w.setGravity(Gravity.CENTER);
        mListenersHandler = new ListenersHandler(this);
    }
public class Dialog implements DialogInterface, Window.Callback,
        KeyEvent.Callback, OnCreateContextMenuListener, Window.OnWindowDismissedCallback {}

上面这段代码,表明Dialog能够接受Window的Callback,消失事件,按键事件(优先于宿主Activity)

这表明Dialog可以做很多事情,因为它拥有属于自己的Window,能够监听按键的事件,大家都有各种方式让Fragment变相监听到返回键。如何只需要一个页面的话,也可以考虑DialogFragment。
Demo: 设置Window的大小

Window window = getDialog().getWindow();
        DisplayMetrics dm = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
        getDialog().getWindow().setLayout(dm.widthPixels,
                getDialog().getWindow().getAttributes().height);
        window.setBackgroundDrawable(new ColorDrawable(0xff000000));
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        // 底部显示
        layoutParams.gravity = Gravity.BOTTOM;
        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;

        layoutParams.windowAnimations = com.jiuyuhulian.LiveRoom.R.style.BottomToTopAnim;
        window.setAttributes(layoutParams);

DialogFragment实现的接口方法。

public void onCancel(DialogInterface dialog) {
    }

public void onDismiss(DialogInterface dialog) {
    if (!mViewDestroyed) {
        // Note: we need to use allowStateLoss, because the dialog
        // dispatches this asynchronously so we can receive the call
        // after the activity is paused.  Worst case, when the user comes
        // back to the activity they see the dialog again.
        dismissInternal(true);
    }
}

对比, 简单的解释就是,当我们锁屏的时候,我们的Dialog会调用dismissAllowingStateLoss(), 当解锁时,DialogFragment会再次显示出来,而dissmiss则会不保存这个状态。

public void dismiss() {
        dismissInternal(false);
    }
public void dismissAllowingStateLoss() {
        dismissInternal(true);
    }

dismissInternal(boolean allowStateLoss)

void dismissInternal(boolean allowStateLoss) {
        if (mDismissed) {
            return;
        }
        mDismissed = true;
        mShownByMe = false;
        if (mDialog != null) {
            mDialog.dismiss();
            mDialog = null;
        }
        mViewDestroyed = true;
        if (mBackStackId >= 0) {
            getFragmentManager().popBackStack(mBackStackId,
                    FragmentManager.POP_BACK_STACK_INCLUSIVE);
            mBackStackId = -1;
        } else {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.remove(this);
            if (allowStateLoss) {
                ft.commitAllowingStateLoss();
            } else {
                ft.commit();
            }
        }
    }
    @Override
    public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
    }

监听返回键

getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialogInterface, int i, KeyEvent keyEvent) {
                // 这里会优先监听到Key事件,最主要的是back键,注意back键有down和up事件
                return false;
            }
        });

设置要在getLayoutInflater()方法之前,也就是在页面初始化之前

public void setStyle(int style, int theme) {
        mStyle = style;
        if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) {
            mTheme = com.android.internal.R.style.Theme_DeviceDefault_Dialog_NoFrame;
        }
        if (theme != 0) {
            mTheme = theme;
        }
    }

    public static final int STYLE_NO_TITLE = 1; // 没标题
    public static final int STYLE_NO_FRAME = 2; // 无框的(没有层级)
    public static final int STYLE_NO_INPUT = 3; // 不可输入

你可能感兴趣的:(Android)