Android 自定义布局的dialog宽高变形问题

这几天在做自定义布局的dialog时,踩了不少的坑,现在记录下自认为最大的坑。

首先,我们来创建一个定义dialog布局的xml文件。dlg_test.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello world"/>
 
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button"/>
</LinearLayout>

在这个布局文件中,只放了一个TextView和一个Button,宽度都为wrap_content,最外层是一个宽度为match_parent的LinearLayout。然后在main_activity中放置一个按钮,便于弹出该dialog。以下为MainActivity中弹出dialog的代码:

open_dlg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDialog dlg = new AlertDialog.Builder(MainActivity.this, R.style.testDlg).create();
                dlg.show();
                dlg.setContentView(R.layout.dlg_test);
            }
        });

dialog的样式是我在style文件中定义的,只需要在style文件中加入下面这行代码即可:

<style name="testDlg" parent="android:Theme.Dialog"></style>

这样,一个简单的自定义dialog就实现了,效果如下:

可以看到,这个dialog的大小刚好为容纳所有控件的大小。

接下来我们改变一下button的宽度,改为match_parent。可想而知,此时button应该横占一行,根据android studio的可视化界面我们也可以看到确实如此:

我们猜想,dialog应该也会随之被撑大吧。但是当dialog显示出来时,我们的内心是奔溃的:

大家别以为我把第一幅图copy下来了,这真的是改变后的dialog,好像没什么变化呢,这是为什么啊?

经过我的不断折腾之后,我终于弄懂了是为什么。

这是因为在dialog中,我们的最外层布局,即上面的LinearLayout的宽度和高度都变成了wrap_content。为了证明这一点,我们把dlg_test.xml中的LinearLayout的宽度高度都改为wrap_content

dlg_test.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="hello world"/>
 
    <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="button"/>
</LinearLayout>

可视化界面如下:

图中虚线代表当前LinearLayout的大小,仔细看,我们会发现,这个与我们显示的dialog是一样大小的。据此可以知道,dialog最外层的布局宽度和高度确实被设定为wrap_content。

当最外层布局宽度为wrap_content时,其宽度值是:所有layout_width为wrap_content的直接子控件的宽度的最大值(这里的直接子控件指的是第二层布局或者控件),这样的话,大于该最大值的控件就会出现一个问题——宽度只能全部变为这个最大值,所以我们的button即使设置了match_parent,也无法将dialog撑开。而且,如果我们某些控件所显示的文本太多时,这个最大值宽度并不一定能容纳这些文本,此时就会出现文本换行甚至是不可见的情况。

为了能更好的理解这一点,下面再来修改一下dlg_test.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">
 
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="hello world"/>
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="222"/>
    </LinearLayout>
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1"/>
 
    <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="button"/>
</LinearLayout>

这里我增加了一个第二层布局LinearLayout,宽度高度都为match_parent,其中还包含了一个文本为222的TextView,并且TextView的宽度高度都为wrap_content。

另外我还加了一个第二层控件TextView,文本为1,宽度高度都为wrap_content。 

接下来我们看一下可视化界面的效果以及dialog的真实效果:


可以看到,这两个的效果是一模一样的,而且dialog的宽度只刚好包含了文本为1的TextView,而不能刚好包含其他控件,所以可知dialog宽度的取值规律确实为:所有layout_width为wrap_content的直接子控件的宽度的最大值(这里的直接子控件指的是第二层布局或者控件)。

那么,为了保证我们想展示的内容不变形,我们在书写dialog的布局文件时,最外层一开始就都用wrap_content的宽度,这样就能在可视化界面中看到真正的dialog模样,同时第二层布局或者控件要统一宽度,要么都为wrap_content,要么都为match_parent,这样才能确保控件大小的正常


版权声明:本文为CSDN博主「linkdust」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/linkdust/article/details/49707337

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值