永发信息网

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 );
}
}
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯