Compose随记 - 设置视图宽高比

3,487 阅读2分钟

在View-ViewGroup系统中,我非常喜欢ConstraintLayout这个ViewGroup,而其中有一个我非常喜欢的属性:constraintDimensionRatio。通过这个属性,我们可以在不清楚用户设备尺寸且不希望固定视图尺寸的时候,让视图根据约束,以某一个比例来缩放自己。

在Compose中,你谷哥哥也很贴心的为大伙准备了Compose版本的ConstraintLayout,主要的用法就是通过Modifier.constrainAs(ConstraintLayoutReference) {}来为视图添加约束条件。

但是我找了一圈,也没搞明白如何在constrainAs() {}这个方法里面实现类似constraintDimensionRatio属性一样的效果。转念一想,modifier说到底,其实也是用来约束视图的一个属性嘛!结果还真的在Modifier中找到这样的一个方法:aspectRatio(Float, Boolean)。下面是它的方法介绍:

Attempts to size the content to match a specified aspect ratio by trying to match one of the incoming constraints in the following order:

Constraints.maxWidth, Constraints.maxHeight, Constraints.minWidth, Constraints.minHeight if matchHeightConstraintsFirst is false (which is the default),

or Constraints.maxHeight, Constraints.maxWidth, Constraints.minHeight, Constraints.minWidth if matchHeightConstraintsFirst is true.

The size in the other dimension is determined by the aspect ratio. The combinations will be tried in this order until one non-empty is found to satisfy the constraints.

If no valid size is obtained this way, it means that there is no non-empty size satisfying both the constraints and the aspect ratio, so the constraints will not be respected and the content will be sized such that the Constraints.maxWidth or Constraints.maxHeight is matched (depending on matchHeightConstraintsFirst).

Example usage:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.width

Box(Modifier.width(100.dp).aspectRatio(2f).background(Color.Green))

通过例子不难发现,这个方法其实就是做到了之前需要通过constraintDimensionRatio属性来实现的效果,做法也和constraintDimensionRatio类似。

该方法传入两个参数:

  1. Float类型的ratio,用来确定视图宽高比;
  2. Bool类型的matchHeightConstraintsFirst,用来指定是否要优先依赖高度(也就是纵向)的约束,换句话说,该值为true时,以纵向(高度方向)的约束为基准,来调整横向宽度。

其中ratio为必传参数,matchHeightConstraintsFirst可选,默认情况下matchHeightConstraintsFirst为false,也就是以横向(宽度方向)的约束为基准,来调整纵向高度。

很显然,这个方法和之前View-ViewGroup体系中的参数不同之处在于,在Compose中,你不需要依赖ConstraintLayout来实现宽高比的限制,而是在任意一种布局中都可以使用,属于是ConstraintLayout的属性下放了。