Android で ViewGroup を拡張しています。現在、テストのためだけに、このビュー グループに子ビューを 1 つだけ追加しています。これは、コードによってインスタンス化された TextView です。
ViewGroup の onMeasure() で を呼び出すとchild.measure()
、作成時に WRAP_CONTENT を高さレイアウト パラメータとして渡しますが、子はその高さを画面全体の高さとして測定します。ただし、を使用して子供を測定するとmeasureChildWithMargins
、正しい身長が返されます。どうしてこれなの?
public class CustomViewGroup extends ViewGroup {
public CustomViewGroup (Context context) {
super(context);
init(context);
}
private void init(Context context) {
// create header text view
addView(createTitleHeader(context));
}
private TextView createTitleHeader(Context context) {
TextView result = new TextView(context);
result.setLayoutParams(new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
result.setBackgroundColor(Color.RED);
return result;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
// the following line scales the TextView's height to the entire screen
child.measure(widthMeasureSpec, heightMeasureSpec);
//...while the following line works perfectly
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
}
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (changed) {
// get view group measurements
final int viewLeft = getPaddingLeft();
final int viewTop = getPaddingTop();
final int viewRight = right - left - getPaddingRight();
final int viewBottom = bottom - top - getPaddingBottom();
// temp rect used for measuring views
final Rect rect = new Rect();
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
// get child params
final LayoutParams lp = child.getLayoutParams();
final int childWidth = child.getMeasuredWidth();
final int childHeight = child.getMeasuredHeight();
// calculate rect
rect.left = viewLeft;// + lp.leftMargin;
rect.top = viewTop;// + lp.topMargin;
rect.right = viewLeft + childWidth;// - lp.rightMargin;
rect.bottom = viewTop + childHeight;
// layout
child.layout(rect.left, rect.top, rect.right, rect.bottom);
}
}
}
}
}