Android Dialog 不能全屏显示问题

629 阅读1分钟

Dialog 宽度不能像Activity那样宽度铺满屏幕整个屏幕,造成屏幕空间的浪费,而且不能自定义Margin.

弄清这个问题,需要研究Dialog是如何显示的?
  1. 创建Dialog
Dialog dialog = new Dialog(context);

2.Dialog 设置内容

dialog.setContentView(layoutId);

3.通过跟踪代码, 界面的显示是根据Window的属性width和height来确定

Window window = dialog.getWindow();
WindowManager.LayoutParams attributes = window.getAttributes();
attributes.width = ScreenUtil.getScreenWidth(context) - 2 * padding;
attributes.height = WindowManager.LayoutParams.WRAP_CONTENT;

4.通过分析,发现 width和height 这两个属性是在这个setContentView 之后后改变的

Dialog.java
public void setContentView(@LayoutRes int layoutResID) {
    mWindow.setContentView(layoutResID);
}

5.分析下一步,mWindow 的实现类 PhoneWindow

PhoneWindow.java
public void setContentView(int layoutResID) {
    // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
    // decor, when theme attributes and the like are crystalized. Do not check the feature
    // before this happens.
    if (mContentParent == null) {
        installDecor();
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        mContentParent.removeAllViews();
    }

private void installDecor() {
    mForceDecorInstall = false;
    if (mDecor == null) {
        mDecor = generateDecor(-1);
        mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
        mDecor.setIsRootNamespace(true);
        if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
            mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
        }
    } else {
        mDecor.setWindow(this);
    }
if (mContentParent == null) {
    mContentParent = generateLayout(mDecor);
    
    
protected ViewGroup generateLayout(DecorView decor) {
...
mIsFloating = a.getBoolean(R.styleable.Window_windowIsFloating, false);
if (mIsFloating) {
    setLayout(WRAP_CONTENT, WRAP_CONTENT);

public void setLayout(int width, int height) {
    final WindowManager.LayoutParams attrs = getAttributes();
    attrs.width = width;
    attrs.height = height;
    dispatchWindowAttributesChanged(attrs);
}

通过 mIsFloating判断来设置 setLayout,设置 LayoutParams attrs 的宽和高,原来秘密 就在这里,如果需要更改属性需要在这个之后重新设置Dialog属性

Window window = dialog.getWindow();
WindowManager.LayoutParams attributes = window.getAttributes();
attributes.width = ScreenUtil.getScreenWidth(context) - 2 * padding;
attributes.height = WindowManager.LayoutParams.WRAP_CONTENT;

然后在调用

dialog.show();