什么是onMeasure()的错误?

时间:2016-08-28 01:54:04

标签: java android view

我正在尝试编写一个简单的自定义视图,但是我遇到了一个问题:onMeasure()工作不正常。 我的onMeasure()代码:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        Log.d("ad","Width mode: "+widthMode+"\nHeight mode: "+heightMode);
        int width = 0, height = 0;
        textLayout = null;

        switch (heightMode) {
            case MeasureSpec.EXACTLY:
                height = heightSize;
                textLayout = new StaticLayout(textString, textPaint, height, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);
                //Log.d("ad","Checkpoint 1: "+height);
                break;
            case MeasureSpec.AT_MOST:
                textLayout = new StaticLayout(textString, textPaint, heightSize, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);
                //Log.d("ad","Checkpoint 2: "+heightSize);
                int lineCount = textLayout.getLineCount();
                if (lineCount > 0) {
                    if (lineCount==1){
                        height = (int) textLayout.getLineWidth(0);
                    } else {
                        height = heightSize;
                    }
                }
                break;
            case MeasureSpec.UNSPECIFIED:
                textPaint.getTextBounds(textString, 0, textString.length(), textBounds);
                height = textBounds.width();
                break;
        }

        switch (widthMode) {
            case MeasureSpec.EXACTLY:
                width = widthSize;
                //Log.d("ad","Checkpoint 3!");
                break;
            case MeasureSpec.AT_MOST:
                if (textLayout!=null) {
                    int lineCount = textLayout.getLineCount();
                    if (lineCount > 0) {
                        width = Math.min(textLayout.getLineBottom(lineCount-1), widthSize);
                        //Log.d("ad","Checkpoint 4: "+lineCount);
                    }
                } else {
                    width = Math.min(textBounds.height(), widthSize);
                }
                break;
            case MeasureSpec.UNSPECIFIED:
                if (textLayout!=null) {
                    int lineCount = textLayout.getLineCount();
                    if (lineCount > 0) {
                        width = textLayout.getLineBottom(lineCount-1);
                    }
                } else {
                    width = textBounds.height();
                }
                break;
        }

        setMeasuredDimension(width, height);
    }

这是我现在唯一的方法。它大部分工作正常,但如果我使用width=wrap_contentheight=200dp(例如),它会计算宽度错误并打印下一个日志:

D/ad: Width mode: -2147483648 (AT_MOST) Height mode: -2147483648 (AT_MOST)
D/ad: Width mode: 1073741824 (EXACTLY) Height mode: 1073741824 (EXACTLY)

布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.don.verticaltextview.VerticalTextView
        android:layout_width="wrap_content"
        android:layout_height="200dp"
        android:textSize="24sp"
        android:textColor="#111"
        android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum" />

</RelativeLayout>

但是onMeasure()widthMode=AT_MOSTheightMode=EXACTLY的联系方式在哪里?

1 个答案:

答案 0 :(得分:0)

问题发生在我自定义视图的父级RelativeLayout中,它调用了onMeasure()两次并且测量规格错误。在其他布局中,它按预期工作,onMeasure()只调用一次。