RelativeLayout Not Properly Updating Width Of Custom View
I have this container class that is used to make one of the dimensions, either the width or height, a ratio of the other dimension. For instance, I want a 16:9 layout container whe
Solution 1:
I've actually tried to do exactly what you're trying to do before, that is, make a View
be as big as possible while retaining some aspect ratio (i.e. square or 4:3 or something like that).
My problem was that when my View was in a ScrollView
the size got computed incorrectly. I wasn't able to figure this one out, but I'll post my code below just in case it helps. It's really similar to your code, but I'm inheriting from FrameLayout
and I end up calling super.onMeasure()
.
I double checked the project I was using this in, and I do actually have it as a direct child of RelativeLayout
.
Java:
/**
* A FrameLayout which tries to be as big as possible while maintaining a given ratio between its width and height.
* Formula: Height = Width / ratio;
* Usage:
* 1) Set layout_width and layout_height to "match_parent"
* 2) For 4:3 for example, set ratio to 4/3 = 1.333333 etc. Or don't specify, and it will be square by default.
*/
public class RatioFrameLayout extends FrameLayout
{
private final static float DEFAULT_RATIO = 1f;
private float ratio;
private boolean measured = false;
public RatioFrameLayout(Context context)
{
super(context);
}
public RatioFrameLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
readAttributes(context, attrs);
}
public RatioFrameLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
readAttributes(context, attrs);
}
private void readAttributes(Context context, AttributeSet attrs)
{
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RatioFrameLayout);
String value = a.getString(R.styleable.RatioFrameLayout_ratio);
try
{
ratio = Float.parseFloat(value);
}
catch (Exception e)
{
ratio = DEFAULT_RATIO;
}
a.recycle();
}
public float getRatio()
{
return ratio;
}
public void setRatio(float ratio)
{
this.ratio = ratio;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int targetWidth = getMeasuredWidth();
int targetHeight = Math.round((float)getMeasuredWidth() / ratio);
if (targetHeight > getMeasuredHeight() && getMeasuredHeight() != 0)
{
targetWidth = Math.round(getMeasuredHeight() * ratio);
targetHeight = getMeasuredHeight();
}
super.onMeasure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(targetHeight, MeasureSpec.EXACTLY));
}
private void printMeasureSpec(String description, int value)
{
int mode = MeasureSpec.getMode(value);
String modeName = mode == MeasureSpec.AT_MOST ? "AT_MOST"
: mode == MeasureSpec.EXACTLY ? "EXACTLY" : "UNSPECIFIED";
DLog.d(String.format("Measure spec for %s, mode = %s, size = %d", description, modeName, MeasureSpec.getSize(value)));
}
}
attrs.xml
:
<resources>
<declare-styleable name="RatioFrameLayout">
<attr name="ratio" format="string|reference" />
</declare-styleable>
</resources>
Post a Comment for "RelativeLayout Not Properly Updating Width Of Custom View"