layout_*的一些注意事项
在Android UI的开发中layout_*应该是用的很多的,但其中有很多的坑想必大家也碰到过,今天就来写写自己碰到的!之后如果还有碰到就在添加。
layout_width
| layout_height
起因
先来说说起因,做一个自定义的Dialog。这本来是很简单的事情,以前也做过很多次包括PopupWindow
。可能是之前到处借鉴别人的代码,没怎么注意,今天自己动手写。出现了个之前出现却没仔细解决的问题!然后就花了一下午甚至还去stackoverflow上提了一发问,不得不说国外的环境就是比国内的好。国内的论坛”杂鱼”太多。真正好好回答你问题的没几个!但也不乏有细心的大神指导~
问题描述见stackoverflow:
http://stackoverflow.com/questions/37854419/why-can-android-alertdialogs-width-and-height-1
问题描述
看了stackoverflow的人应该知道我出现了什么样的问题,问题总的来说是4个:
- 问题1:我在
AlertDialog
实例化的时候,直接获取其高度和宽度,结果得到-1 ,出现-1的原因 - 问题2:
setLayout
必须在dialog.show()
之后执行,理由是? - 问题3:
getWindow.setLayout(int width, int height)
这里width
和height
的单位是什么? - 问题4:为何xml文件中的
LinearLayout
中的layout_width
和layout_height
没有起到作用!
问题解决
问题1:
AlertDialog
实例化AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).setView(view).create();
后,AlertDialog
并没有真正被创建。只有当dialog.create()
[API 21才允许使用]和dialog.show()
之后才真正被创建。所以当我这个时候去获取它的高度和宽度的时候会得到”-1”,这个“-1”是有深意的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static final int FILL_PARENT = -1;
/**
* Special value for the height or width requested by a View.
* MATCH_PARENT means that the view wants to be as big as its parent,
* minus the parent's padding, if any. Introduced in API Level 8.
*/
public static final int MATCH_PARENT = -1;
/**
* Special value for the height or width requested by a View.
* WRAP_CONTENT means that the view wants to be just large enough to fit
* its own internal content, taking its own padding into account.
*/
public static final int WRAP_CONTENT = -2;
“-1”即全屏。默认是全屏的。如果我们把1
2WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
Log.d("TAG", "First lp width and height" + lp.width + " " + lp.height);
我门得到的结果为“-2“。至于为何我也不知所以!
问题2
问题2和问题1是一样的问题,同样是由于Dialog还未生成,所以在.show()
之后,setLayout()
是可以起到作用的!
问题3
这里的int width
和int height
都是px单位的。可以看到我设置了TextView的高度和宽度分别是200dp
设置了Dialog的高度和宽度分贝是500px
则会出现下面的效果:
发现200dp
和500px
差的不多。
问题4
这个问题就很高深了,具体为啥是由国外友人告诉我的。
layout_ prefixed attributes are set on a LayoutParams object provided by parent view. Since there’s no parent, there are no LayoutParams you can work with. Try setting android:minHeight and android:minWidth instead.
国外友人说的很详细,layout_*
这个属性要能使用必须有父视图(父布局)。如果你不是很懂(其实我也不是很懂),看看郭神的这篇博客可能会有点体会:
http://blog.csdn.net/guolin_blog/article/details/12921889
平时我们经常使用layout_width和layout_height来设置View的大小,并且一直都能正常工作,就好像这两个属性确实是用于设置View的大小的。而实际上则不然,它们其实是用于设置View在布局中的大小的,也就是说,首先View必须存在于一个布局中
这也就是为啥有时候在xml那边设置了宽、高,但是却没能在界面中体现出来的某一个原因。
layout_weight
链接在这里:http://blog.csdn.net/cuihaoren01/article/details/51373887
layout_gravity
| gravity
android:gravity
是用于设置View组建对齐方式。是针对控件里面的元素来说的,用来控制元素在该空间里的显示位置。android:layout_gravity
用于设置Container组建的对齐方式。是针对控件本身而言,用来控制该控件在包涵该控件的父控件的位置。- 特殊情况:当我们采用
LinearLayout
布局时:
1)当android:orientation = veritical
时,android:layout_gravity
只有水平方向的设置才起作用,垂直方向的设置是不起作用的
2)当android:orientation = horizontal
时,android:layout_gravity
只有垂直方向的设置才起作用,水平方向的设置不起作用。
之后如果还出现什么问题或者Bug的话在补充也希望有人能给我补充!