覆盖RelativeLayout的onMeasure()以约束其纵横比

时间:2011-12-20 14:38:59

标签: android relativelayout

我有一个扩展的RelativeLayout,当使用RelativeLayout.LayoutParams以编程方式定位和调整大小时,需要将自己限制为给定的宽高比。通常,我希望它将自己约束为1:1,这样如果RelativeLayout.LayoutParams包含width为200且height为100,则自定义RelativeLayout将自己约束为100 x 100.

我已经习惯于在普通的自定义onMeasure()中覆盖View以实现类似的目标。例如,我创建了自己的SVG图像转换器,并且自定义View使SVG图像具有被覆盖的onMeasure(),以确保对setMeasuredDimension()的调用包含(a)的维度符合原始测量规范,(b)匹配原始SVG图像的纵横比。

回到我希望以类似方式限制自己的自定义RelativeLayout,我已尝试覆盖onMeasure(),但我没有取得多大成功。知道RelativeLayout onMeasure()执行所有子View展示位置,我目前通常尝试做的事情,但没有预期的结果,是覆盖onMeasure(),以便我最初首先修改维度规范(即应用我想要的约束),然后调用super.onMeasure()。像这样:

@Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec){

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);      
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    // Restrict the aspect ratio to 1:1, fitting within original specified dimensions
    int chosenDimension = Math.min(chosenWidth, chosenHeight);
    widthMeasureSpec = MeasureSpec.makeMeasureSpec(chosenDimension, MeasureSpec.AT_MOST);
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(chosenDimension, MeasureSpec.AT_MOST);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

当我这样做时,实际发生的是,奇怪的是,高度被正确限制,但宽度不是。举例说明:

  • RelativeLayout.LayoutParams中指定200的高度和100的宽度会导致我的自定义RelativeLayout的高度为100,宽度为100. - >正确。

  • RelativeLayout.LayoutParams中指定高度100和宽度200会导致我的自定义RelativeLayout高度为100,宽度为200. - >不正确。

我意识到我可以在调用类中应用我的宽高比约束逻辑,将RelativeLayout放在首位(同时我可能会这样做以解决这个问题) ,但实际上这是我希望RelativeLayout本身执行的实现细节。

澄清:我回读的结果宽度和高度值来自使用getWidth()getHeight()。在再次执行布局过程之后,将来某些时候会回读这些值。

1 个答案:

答案 0 :(得分:17)

我现在已经解决了这个问题,同时设置了widthheight当前持有的LayoutParams的{​​{1}}和RelativeLayout

onMeasure()

现在可以根据需要运行:@Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec){ int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); // Restrict the aspect ratio to 1:1, fitting within original specified dimensions int chosenDimension = Math.min(widthSize, heightSize); widthMeasureSpec = MeasureSpec.makeMeasureSpec(chosenDimension, MeasureSpec.AT_MOST); heightMeasureSpec = MeasureSpec.makeMeasureSpec(chosenDimension, MeasureSpec.AT_MOST); getLayoutParams().height = chosenDimension; getLayoutParams().width = chosenDimension; super.onMeasure(widthMeasureSpec, heightMeasureSpec); } (以及对RelativeLayoutgetWidth()的后续调用)的大小现在同意我覆盖的getHeight()中应用的大小限制。