- Layout_x:表示控件与父控件之间的关系,不带layout的属性表示控件中文本的格式
- 带Layout_weight的控件width计算方法:首先计算剩余空间,剩余空间可以是整可以是负,剩余空间=屏幕width-所有控件所需要的width,然后剩余空间乘以weight所占的比例再加到width上就是实际的width
- 布局是组件是组件在Activity中的呈现方式,即组件大小,间距和对齐方式等,Android中常见的布局以下几种:
- 线性布局:按照垂直或者水平方式布局组件
- 帧布局:组件从屏幕的左上角布局
- 表格布局:按照行列方式布局组件
- 相对布局:相对于其他组件的布局方式
- 绝对布局(已过期):按照绝对坐标来布局组件
- MeasureSpec的三个常量的含义:
- MeasureSpec.UNSPECIFIED:parent不对子元素施加影响,子元素想多大就多大
- MeasureSpec.EXACTLY:parent决定了子元素的确定大小,不管子元素想要多大
- MeasureSpec.AT_MOST:子元素至多能达到的大小
- 当我们设置width或height为fill_parent时,View在测量时调用view的onMeasure方法传入的模式是EXACTLY,因为view会占据父容器剩余的空间,所以它大小是确定的。而当设置为 wrap_content时,容器传进去的是AT_MOST, 表示子view的大小最多是多少,这样子view会计算自己的尺寸并与容器分配的大小比较取小值作为自己的size,wrap_content时只有子view才能计算自己的宽和高。当子view的大小设置为精确值时,容器传入的是EXACTLY。所以通常自定义View时,计算view的size的onMeasure方法的实现过程如下:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { /** * 设置宽度 */ int specMode = MeasureSpec.getMode(widthMeasureSpec); int specSize = MeasureSpec.getSize(widthMeasureSpec); if (specMode == MeasureSpec.EXACTLY)// match_parent,exactly { Log.e("xxx", "EXACTLY"); mWidth = specSize; } else { /* 计算期望的宽度desireWidth*/ ........................ if (specMode == MeasureSpec.AT_MOST)// wrap_content mWidth = Math.min(desireWidth, specSize); Log.e("xxx", "AT_MOST"); } } /*** * 设置高度 */ specMode = MeasureSpec.getMode(heightMeasureSpec); specSize = MeasureSpec.getSize(heightMeasureSpec); if (specMode == MeasureSpec.EXACTLY)// match_parent,exactly { mHeight = specSize; } else { /*计算期望的高度desireHeight*/ if (specMode == MeasureSpec.AT_MOST)// wrap_content { mHeight = Math.min(desireHeight, specSize); } } setMeasuredDimension(mWidth, mHeight); }
- onMeasure(int widthMeasureSpec, int heightMeasureSpec),以widthMeasureSpec为例:
- Padding 是view的边界与view的content之间的距离,无法针对背景设置Padding, padding与margin的布局如图: