Q:

Whats's wrong with onMeasure()?

I'm trying to write a simple custom view, but I have a problem: onMeasure() works incorrectly.
My onMeasure() code:
@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);
    }

This is the only method that I overrided for now. It mostly works fine, but if I use width=wrap_content and height=200dp (for example), it calculates width wrong and prints next log:
D/ad: Width mode: -2147483648 (AT_MOST) Height mode: -2147483648 (AT_MOST)
D/ad: Width mode: 1073741824 (EXACTLY) Height mode: 1073741824 (EXACTLY)

Layout:
<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>

But where is onMeasure() call with widthMode=AT_MOST and heightMode=EXACTLY?

A:

The problem was in RelativeLayout that is the parent of my custom view, it calls onMeasure() twice and with wrong measurment specs. In other layouts it works as expected and onMeasure() is called only once.

