Skip to content Skip to sidebar Skip to footer

Telling The Android Layout Inflater How Large "wrap_content" Should Be

I want to create a custom View, such that when it is inflated with wrap_content as one of the dimension parameters and match_parent as the other, it will have a constant aspect rat

Solution 1:

You can always check for compliance to aspect ratio in onMeasure.

not a full answer I know, but it should lead you there ;)


Solution 2:

I've now solved this with the following code. It's worth mentioning in passing that the class I'm overriding is a custom ViewGroup with custom children, all using the inherited onMeasure. The children are created and added at construction-time, and I would assume as a matter of course that this is necessary.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    float width = MeasureSpec.getSize(widthMeasureSpec);
    final int widthMode = MeasureSpec.getMode(widthMeasureSpec);

    float height = MeasureSpec.getSize(heightMeasureSpec);
    final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    float nominalHeight = getResources().getInteger(R.integer.nominalheight);
    float nominalWidth = getResources().getInteger(R.integer.nominalwidth);

    float aspectRatio = nominalWidth / nominalHeight;

    if( widthMode == MeasureSpec.UNSPECIFIED ) { //conform width to height
        width = height * aspectRatio;
    }
    else if (heightMode == MeasureSpec.UNSPECIFIED ) { //conform height to width
        height = width / aspectRatio;
    }
    else if( width / height > aspectRatio //too wide
            && ( widthMode == MeasureSpec.AT_MOST )
            ) { 
        width -= (width - height * aspectRatio);
    }
    else if( width / height < aspectRatio //too tall
            && ( heightMode == MeasureSpec.AT_MOST )
            ) { 
        height -= (height - width / aspectRatio);
    }

    int newWidthMeasure = MeasureSpec.makeMeasureSpec((int)width, MeasureSpec.AT_MOST);
    int newHeightMeasure = MeasureSpec.makeMeasureSpec((int)height, MeasureSpec.AT_MOST);
    measureChildren(newWidthMeasure, newHeightMeasure);

    setMeasuredDimension((int)width, (int)height);
}

I'm defining the aspect ratio in terms of a nominal rectangle in resources, but obviously there are plenty of other ways to do this.

With thanks to Josephus Villarey who pointed me at onMeasure(...) in the first place.


Post a Comment for "Telling The Android Layout Inflater How Large "wrap_content" Should Be"