为什么可以Android AlertDialog width and height = -1

Why can Android AlertDialog's width and height = -1

我有三个问题要问 AlertDialog。首先,我会post我的代码然后问我的问题。

<LinearLayout
android:id="@+id/l2"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@android:color/holo_orange_light"
xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView
        android:layout_width="200dp"
        android:layout_height="600dp"
        android:text="Test Test"
        android:textSize="40sp"
        android:background="@android:color/holo_green_light"
        android:textColor="@android:color/black"/>

这是在AlertDialog中显示的视图,在activity_main.xml中,我设置了一个按钮来打开AlertDialog,下面是listener的代码。

  btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.popup_window, null);
            AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).setView(view).create();
            WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
            Log.d("TAG", "First lp width and height" + lp.width + "  " + lp.height);
            dialog.show();
            Window dialogWindow = dialog.getWindow();
            dialogWindow.setLayout(500,500);
            WindowManager.LayoutParams lp2 = dialogWindow.getAttributes();
            Log.d("TAG", "lp2 width and height" + lp2.width + "  " + lp2.height);

        }
    });

logcat信息截图如下: Log 问题:

  1. 如你所见,Dialog的宽高都是-1,我没有 知道原因了。
  2. dialogWindow.setLayout(500,500);是在dialog.show之后执行的。当我把dialogWindow.setLayout(500,500);放在dialog.show前面时,发现不起作用。为什么
  3. getWindow.setLayout(int width, int height);宽度和高度的单位是什么? ScreenShot
 btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.popup_window, null);
        AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).setView(view).create();
        WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
        Log.d("TAG", "First lp width and height" + lp.width + "  " + lp.height); <---------
        dialog.show();     <----------- you show the window here, so its size can be calculated. Before this, it doesn't exist. This is why you get -1 -1
        Window dialogWindow = dialog.getWindow();
        dialogWindow.setLayout(500,500);
        WindowManager.LayoutParams lp2 = dialogWindow.getAttributes();
        Log.d("TAG", "lp2 width and height" + lp2.width + "  " + lp2.height);

    }
});

在第一次登录前尝试 dialog.show ;)

1 & 2
在您调用 .show().create() 之前,不会创建警报对话框。因此,如果您在创建之前调用您正在调用的方法,它只会 return 一些默认值。

如果你这样做

AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).setView(view).create();
dialog.create();
WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
Log.d("TAG", "First lp width and height" + lp.width + "  " + lp.height);

它应该显示正确的值。

3
与您在 xml 中输入的值相同。可以是 MATCH_PARENTWRAP_CONTENT 或精确值。精确值以像素为单位。

另见 the docs for Window

As you can see, The width and height of Dialog equals -1, I don't know the reason.

-1WindowManager.LayoutParams.widthWindowManager.LayoutParams.height 的默认值。

-1 也称为 MATCH_PARENT,这意味着对话框将尝试占据尽可能多的空间 space,同时尊重最大和最小宽度和高度等主题属性。

dialogWindow.setLayout(500,500) is executed after dialog.show(). When I put it in front of dialog.show() it does't work. Why?

dialog.show()dialog.create() 之前,AlertDialog 尚未安装其内容。它在内部调用 PhoneWindow 的以下方法:

@Override
public void setContentView(View view) {
    setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}

这也应该解释默认值的来源。您对 setLayout 的调用现在应该会产生预期的结果。

来源:@TimCastelijns

getWindow.setLayout(int width, int height) What is the unit of the width and height?

单位是像素。您还可以使用 WRAP_CONTENTMATCH_PARENT 常量。

如果您要使用此方法,请避免对像素进行硬编码,因为在不同的屏幕上您会获得不同的视觉效果。这些方法将帮助您:

/** Precise decimal value, use for translation. */
public static float dpToPx(Context context, int dp) {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}

/** Rounded down value, use for offsets, paddings, margins. */
public static int dpToPxOffset(Context context, int dp) {
    return (int) (dpToPx(context, dp));
}

/** Rounded up value, use for sizes. */
public static int dpToPxSize(Context context, int dp) {
    return (int) (0.5f + dpToPx(context, dp));
}

备注:

以下行将被忽略。

android:layout_width="200dp"
android:layout_height="200dp"

layout_ 前缀属性设置在 parent 视图提供的 LayoutParams object 上。由于没有 parent,因此没有 LayoutParams 可以使用。尝试设置 android:minHeightandroid:minWidth

Parent 根元素的视图由 inflation:

的参数确定
LayoutInflater.from(context).inflate(R.layout.popup_window, /*parent*/ null);