android 自定义组件中,onMeasure和onlayout的关系是什么样
答案:1 悬赏:20 手机版
解决时间 2021-01-15 02:51
- 提问者网友:暮烟疏雨之际
- 2021-01-14 04:01
android 自定义组件中,onMeasure和onlayout的关系是什么样
最佳答案
- 五星知识达人网友:动情书生
- 2021-01-14 04:40
在onMeasure中计算子View的宽、高,
1.子View的宽、高为包裹内容:
Android | 复制
1
2
3
4
5
6
7
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.AT_MOST));
}
2.指定子View的宽、高:
Android | 复制
1
2
3
4
5
6
7
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY));
}
其中100可以自己随意修改,单位是px(像素),如果想使用dp单位的话
Android | 复制
1
2
3
4
5
//转换dip为px
public static int convertDIP2PX(Context context, int dip) {
float scale = context.getResources().getDisplayMetrics().density;
return (int)(dip*scale + 0.5f*(dip>=0?1:-1));
}
当然也可以去晚上找。
3.不设定子View的宽、高,
Android | 复制
1
2
3
4
5
6
7
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.UNSPECIFIED,
MeasureSpec.UNSPECIFIED);
}
也可以这样写
Android | 复制
1
2
3
4
5
6
7
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
}
当然,如果想要让这个自定义ViewGroup的宽高包裹内容的话,只需要获取子view的宽、高来计算,然后调用setMeasuredDimension(int measuredWidth, int measuredHeight)来设置一下就OK了。
Android | 复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//我这里每行只放一个View,
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidthSize = 0;
int paretnHeightSize = 0;
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY));
parentWidthSize = childView.getMeasuredWidth();
paretnHeightSize += childView.getMeasuredHeight();
}
setMeasuredDimension(parentWidthSize, paretnHeightSize);
}
2onLayout
直接上代码
Android | 复制
1
2
3
4
5
6
7
8
9
10
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
childView.layout(l, t, r, b);
}
}
一步一步看
Android | 复制
1
childView.layout(l, t, r, b);
其中的
l是childView在这个自定义Viewgroup中距离左边的距离,
t是距离上边的距离,
r是自定义Viewgroup中多宽,
b是自定义Viewgroup中多高。
可以这样理解,把这个子View看作一个矩形,那么就可以把l、t看作是矩形左上角的坐标,r、b看作是右下角的坐标,这样比较好理解。
上面已经在onMeasure中计算过子View的宽高了,这里可以直接用,也就是这样写
Android | 复制
1
2
3
4
5
6
7
8
9
10
11
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
//这里获取上面计算过的 子View的宽、高
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
childView.layout(0, 0, childWidth , childHeight );
}
}
1.子View的宽、高为包裹内容:
Android | 复制
1
2
3
4
5
6
7
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.AT_MOST));
}
2.指定子View的宽、高:
Android | 复制
1
2
3
4
5
6
7
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY));
}
其中100可以自己随意修改,单位是px(像素),如果想使用dp单位的话
Android | 复制
1
2
3
4
5
//转换dip为px
public static int convertDIP2PX(Context context, int dip) {
float scale = context.getResources().getDisplayMetrics().density;
return (int)(dip*scale + 0.5f*(dip>=0?1:-1));
}
当然也可以去晚上找。
3.不设定子View的宽、高,
Android | 复制
1
2
3
4
5
6
7
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.UNSPECIFIED,
MeasureSpec.UNSPECIFIED);
}
也可以这样写
Android | 复制
1
2
3
4
5
6
7
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
}
当然,如果想要让这个自定义ViewGroup的宽高包裹内容的话,只需要获取子view的宽、高来计算,然后调用setMeasuredDimension(int measuredWidth, int measuredHeight)来设置一下就OK了。
Android | 复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//我这里每行只放一个View,
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidthSize = 0;
int paretnHeightSize = 0;
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
// 设定子view宽、高
childView.measure(
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY));
parentWidthSize = childView.getMeasuredWidth();
paretnHeightSize += childView.getMeasuredHeight();
}
setMeasuredDimension(parentWidthSize, paretnHeightSize);
}
2onLayout
直接上代码
Android | 复制
1
2
3
4
5
6
7
8
9
10
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
childView.layout(l, t, r, b);
}
}
一步一步看
Android | 复制
1
childView.layout(l, t, r, b);
其中的
l是childView在这个自定义Viewgroup中距离左边的距离,
t是距离上边的距离,
r是自定义Viewgroup中多宽,
b是自定义Viewgroup中多高。
可以这样理解,把这个子View看作一个矩形,那么就可以把l、t看作是矩形左上角的坐标,r、b看作是右下角的坐标,这样比较好理解。
上面已经在onMeasure中计算过子View的宽高了,这里可以直接用,也就是这样写
Android | 复制
1
2
3
4
5
6
7
8
9
10
11
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 1; i < getChildCount(); i++) {
View childView = getChildAt(i);
//这里获取上面计算过的 子View的宽、高
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
childView.layout(0, 0, childWidth , childHeight );
}
}
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯