解析ConstraintLayout的constraintDimensionRatio属性

最近在学习ConstraintLayout时遇到这个属性用不太明白,网上找不到太多详细的资料,参考官网文档和自己的摸索后,把自己的结论跟大家分享下,欢迎批评指正。

首先来看一下官网的解释,如图

image

由文档我们首先能得出以下结论:

  1. 如果要使用这个属性,我们至少要把控件的宽或高中间的一个设置为match constraints,具体怎么设置就不再赘述(XML和View Inspector里都可以).
  2. ratio的比值表示的是宽高比,注意,一直都是宽高比

了解这两点之后,问题来了,系统是怎么知道我们究竟是"以宽为准,按比例去设置高"呢? 还是"以高为准,按比例去设置宽"呢?

我们首先注意到1.里所说的,必须把宽或者高其中之一设为match_constraint,而match_constraint的意思是满足约束。为什么要这么做呢?

举个例子,我们把layout_width设置为match_constraint, layout_height设为固定值100dp,那么很显然,高度是写死的,宽度是需要满足某种约束。此时,如果我们设置了layout_constraintDimensionRatio ="4:1",会出现什么效果呢?很显然,系统会保持高度为100dp,而宽度为高度的4倍,即400dp,从而“match_constraint”满足约束。下面我们来试验一下:

约束width, layout_width="0dp"

XML代码如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.xuqi.constraintlayoutdemo.MainActivity">

    <ImageView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_marginBottom="252dp"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="w,4:1"
        tools:layout_editor_absoluteX="5dp"
        android:background="@color/colorAccent"/>
</android.support.constraint.ConstraintLayout>

preview如下:

以高度为基础按比例设置宽度的示例

显然达到了我们的预期。


约束height,layout_height="0dp"

同理,如果我们把height设为match_constraint,width设为100dp,那么系统就认为我们要以width为准去约束height,我们再加上一句app:layout_constraintDimensionRatio="h,1:2",那么高就是宽的2倍

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.xuqi.constraintlayoutdemo.MainActivity">

    <ImageView
        android:id="@+id/textView"
        android:layout_width="100dp"
        android:layout_height="0dp"
        android:layout_marginBottom="252dp"
        android:background="@color/colorAccent"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="h,1:2"
        tools:layout_editor_absoluteX="5dp" />

</android.support.constraint.ConstraintLayout>

效果如下:

以宽度为基础按比例设置高度的示例

同时约束,layout_width="0dp" && layout_height="0dp"

想象一个场景,我们想在布局里放一张banner,宽度铺满全屏,高度始终为宽度的1/3。那么我们首先为了宽度铺满全屏,需要将width设为match_constraint,又因为高度需要跟宽度形成1:3的比例,所以高度也要同样设置match_constraint,然后将app:layout_constraintDimensionRatio设为"h,3:1"即可

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.xuqi.constraintlayoutdemo.MainActivity">

    <ImageView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/colorAccent"
        android:text="TextView"
        app:layout_constraintDimensionRatio="h,3:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        tools:layout_editor_absoluteY="0dp" />

</android.support.constraint.ConstraintLayout>

效果如下:

宽度为全屏,高度按比例设置的示例

h和w参数的解释

这里我们还需要解释一下app:layout_constraintDimensionRatio的值里面的h和w是什么意思。一般来说,加上h的意思就是,h之后的比例是以w为基础去设置h,即h = w * ratio。反之,写上w的意思是,w = h / ratio (因为 ratio = w / h 代表宽高比)。

以及,如图
image

英文好的同学可以直接看文档

我们可以看到,如果只把一条边设为0dp,那么我们是无需添加h和w的(会有默认值)。因为我们只能去通过未设为0dp的边来约束设为0dp的那条边,也就是说h和w就对应设为0dp的那条边。而如果两条边都设为0dp,那么就必须设置h和w了,不然系统不知道我们想约束哪条边。原理还是一样的,希望哪条边被约束,我们就写哪条边的字母。

总结

以上主要还是想告诉大家这个属性的原理,其实真正去用的时候还是用View Inspector来做的比较多。当我们把至少一条边设为match_constraint后,点击方框左上角的toggle按钮,可以设置对应的比例,方框里显示的横线或竖线表示哪条边是被限制,跟属性里的h和w是对应的。示例如下:

  1. layout_width = "0dp" && layout_height = "0dp"
实例1,点击toggle按钮可以切换约束的边,方框中有一条线横竖变换
  1. layout_height = "0dp"
实例2,只有height是0dp时,点击toggle按钮,方框里始终为竖线
  1. layout_width = "0dp"
实例3,只有weight是0dp时,点击toggle按钮,方框里始终为横线
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容