对于孩子,onMeasure调用getMeasuredWidth或Height返回0

时间:2017-06-05 23:01:50

标签: android android-layout onmeasure

我试图动态地将项目添加到我的CustomView中,并使最终高度与所有添加到一起的子项的大小相同。唯一的问题是child.getMeasuredHeight或child.getMeasuredWidth在运行时始终返回值0。当我进行调试时,它将随机10次中的10次实际上包含我实际期望值为192的数据。如果我还将值硬编码到布局参数而不是使用WRAP_CONTENT,它仍会显示价值为0.是否存在我做错的事情。

xml文件

<CustomLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_marginTop="80dp"
    android:orientation="vertical"
    android:layout_width="200dp"
    android:layout_height="100dp"
    android:id="@+id/custom_layout"
    android:background="@drawable/custom_shape"/>
</CustomLayout>

这是我的CustomLayout.java类的一部分

public class CustomLayout extends LinearLayout {

public CustomLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomLayout(Context context) {
    super(context);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    for(int i=0; i <count; i++) {
        final View child = getChildAt(i);
        if(child.getVisibility() != GONE) {

            maxHeight +=  child.getMeasuredHeight();

        }
    }

    setMeasuredDimension(widthSize,maxHeight);
}

在我的主要活动的一部分

 Button b = new Button(this);
        b.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        b.setText("Sample Test");
        b.setTextSize(14);
        mCustomView.addView(b);

1 个答案:

答案 0 :(得分:0)

在您访问其尺寸之前,您需要让ViewGroup的每个孩子自行测量。这是通过调用[measureChild](https://developer.android.coma/reference/android/view/ViewGroup.html#measureChild(android.view.View,int,int))或[measureChildWithMargins](https://developer.android.coma/reference/android/view/ViewGroup.html#measureChild(android.view.View,int,int))完成的。

查看ViewGroup的开发者指南,了解如何获得子测量值。

// Iterate through all children, measuring them and computing our dimensions
// from their size.
for (int i = 0; i < count; i++) {
    final View child = getChildAt(i);
    if (child.getVisibility() != GONE) {
        // Measure the child.
        measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);

        // Update our size information based on the layout params.  Children
        // that asked to be positioned on the left or right go in those gutters.
        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        if (lp.position == LayoutParams.POSITION_LEFT) {
            mLeftWidth += Math.max(maxWidth,
                    child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
        } else if (lp.position == LayoutParams.POSITION_RIGHT) {
            mRightWidth += Math.max(maxWidth,
                    child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
        } else {
            maxWidth = Math.max(maxWidth,
                    child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
        }
        maxHeight = Math.max(maxHeight,
                child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
        childState = combineMeasuredStates(childState, child.getMeasuredState());
    }
}