如何重新测量layout_weight?

时间:2014-10-28 17:30:51

标签: android android-layout android-view android-layout-weight

在下面的布局xml中,我创建了一个包含两个子视图的水平LinearLayoutLinearLayout孩子应该动态拉伸它的宽度,ImageView的宽度取决于父母的身高。

<LinearLayout android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="horizontal">

    <LinearLayout android:layout_width="0dp"
                  android:layout_height="wrap_content"
                  android:layout_weight="1"
                  android:orientation="vertical">

        <!-- Some children ... -->

    </LinearLayout>

    <MyAspectRatioImageView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:adjustViewBounds="true" />

</LinearLayout>

现在,我想要实现的是这样的结果:

manipulated screenshot

但实际上我得到的是:

original screenshot

这是因为在我的自定义ImageView中,我覆盖onMeasure以保持1:1的宽高比(简化):

override def onMeasure( widthMeasure: Int, heightMeasure: Int )
{
    super.onMeasure( widthMeasure, heightMeasure )

    setMeasuredDimensions( height, height )
}

现在我需要父视图以新的ImageView宽度重新计算宽度共享。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

目前,我通过onMeasure的实施解决了问题,该实施不会调用super。它高度关注所描述的场景,并且在其他地方使用时可能很容易破坏。代码也在Scala中,对不起。

override def onMeasure( widthMeasure: Int, heightMeasure: Int )
{
    ( Option( getDrawable ), ( getMode( widthMeasure ), getMode( heightMeasure ) ) ) match
    {
        // No Drawable
        case ( None, _ ) => setMeasuredDimensions( 0, 0 )
        // Width and height are known
        case ( _, ( EXACTLY, EXACTLY ) ) =>
        {
            // Determine which axis to adjust for the ratio
            val ( width, height ) = ratio.getDominance match
            {
                case 0 => ( getSize( widthMeasure ), ( getSize( widthMeasure ) * ratio.getValue ).toInt )
                case 1 => ( ( getSize( heightMeasure ) * ratio.getValue ).toInt, getSize( heightMeasure ) )
            }

            setMeasuredDimensions( width, height )

            // This call makes this whole thing work in first place
            if( getAdjustViewBounds )
            {
                getLayoutParams.width = width
                getLayoutParams.height = height
            }
        }
        // Only height dimension is known, adjust width to ratio
        case ( _, ( _, EXACTLY ) ) =>
        {
            val height = getSize( heightMeasure )
            setMeasuredDimensions( ( height * ratio.getValue ).toInt, height )
        }
        // Only width dimension is known, adjust height to ratio
        case ( _, ( EXACTLY, _ ) ) =>
        {
            val width = getSize( widthMeasure )
            setMeasuredDimensions( ( width * ratio.getValue ).toInt, width )
        }
        case ( Some( drawable ), ( UNSPECIFIED, UNSPECIFIED ) ) =>
        {
            val ( width, height ) = ratio.getDominance match
            {
                case 0 => ( drawable.getIntrinsicWidth, ( drawable.getIntrinsicWidth * ratio.getValue ).toInt )
                case 1 => ( ( drawable.getIntrinsicHeight * ratio.getValue ).toInt, drawable.getIntrinsicHeight )
            }

            setMeasuredDimensions( width, height )
        }
        case ( Some( drawable ), ( UNSPECIFIED, _ ) ) =>
        {
            setMeasuredDimensions(
                ( drawable.getIntrinsicWidth * ratio.getValue ).toInt,
                drawable.getIntrinsicWidth
            )
        }
        case ( Some( drawable ), ( _, UNSPECIFIED ) ) =>
        {
            setMeasuredDimensions(
                ( drawable.getIntrinsicHeight * ratio.getValue ).toInt,
                drawable.getIntrinsicHeight
            )
        }
        case _ => super.onMeasure( widthMeasure, heightMeasure )
    }
}

https://github.com/Taig/Toolbelt/blob/master/src/main/scala/com/taig/android/widget/image/AspectRatio.scala