ConstraintLayout优化布局-下-代码编写版

发布时间:2021-10-17 07:06:42

上篇已经讲述过ConstraintLayout可视化布局,拖拽的使用。本篇着重讲解ConstraintLayout对布局性能的优化,使用的是代码编写,功能更加灵活。



?


?


?


?


?


?


?


?


?


?


要实现上图展示的页面效果,用其他的包括线性布局,相对布局,或者是百分比布局都很难避免布局嵌套的问题。但是如果使用ConstraintLayout就可以实现一层布局展示页面效果。实现代码如下:



xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

android:id="@+id/tv_banner"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#765"
android:gravity="center"
android:text="我是16:6的导航栏"
app:layout_constraintDimensionRatio="16:6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

android:id="@+id/tv_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:text="哈哈哈"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />


android:id="@+id/tv_one"
style="@style/tv_bottom"
android:background="#f67"
android:text="Tab1"
app:layout_constraintEnd_toStartOf="@id/tv_two"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent" />

android:id="@+id/tv_two"
style="@style/tv_bottom"
android:background="#a67"
android:text="Tab2"
app:layout_constraintEnd_toStartOf="@id/tv_three"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/tv_one" />

android:id="@+id/tv_three"
style="@style/tv_bottom"
android:background="#767"
android:text="Tab3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/tv_two" />

android:id="@+id/tv_suspension"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f12"
android:padding="8dp"
android:text="悬浮球"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.92"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.92" />

android:id="@+id/tv_baseline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:background="#f66"
android:text="哈哈哈嗝"
app:layout_constraintBaseline_creator="30"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_suspension"
app:layout_constraintEnd_toStartOf="@id/tv_suspension"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toStartOf="parent" />



android:layout_width="0dp"
android:layout_height="0dp"
android:background="#f91"
android:gravity="center"
android:text="我是宽度为父布局13%高度为30%的TextView"
app:layout_constraintBottom_toTopOf="@+id/tv_one"
app:layout_constraintEnd_toStartOf="@+id/tv_baseline"
app:layout_constraintHeight_percent="0.3"
app:layout_constraintHorizontal_bias="0.15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.95"
app:layout_constraintWidth_percent="0.13" />

android:id="@+id/guideline_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.65" />

android:id="@+id/guideline_v"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.65" />

android:layout_width="wrap_content"
android:layout_height="30dp"
android:background="#520"
android:gravity="center"
android:text="辅助线TextView"
app:layout_constraintStart_toEndOf="@id/guideline_v"
app:layout_constraintTop_toBottomOf="@id/guideline_h" />


下面将逐个解析ConstraintLayout的属性用法:


一、一个居中的TextView

android:id="@+id/tv_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="哈哈哈"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

这里面出现了4个以app开头的新属性,


app:layout_constraintStart_toStartOf="parent" ? 字面理解就是该控件左侧与父布局的左侧对齐


类似的还有以下几个属性


layout_constraintStart_toEndOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf

这几个属性可以理解为某个方向的“拉力”,app:layout_constraintStart_toStartOf="parent"?即控件的左边有来自于父布局左侧的拉力,当控件受到父布局上下左右四个方向大小相等的拉力时那这个控件自然就居中显示了。这也就是约束布局的核心“力的约束”。


和RelativeLayout的不同,以下内容源于鸿洋的和RL的差异。


android:layout_width="match_parent" android:layout_height="match_parent">

android:id="@+id/id_btn01"
android:layout_width="100dp"
android:text="Btn01"
android:layout_height="wrap_content" />

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/id_btn01"
android:text="Btn02"
android:layout_alignParentRight="true"
/>



?


?


?


那么经过我们刚才的学*,把:layout_toRightOf="@id/id_btn01",layout_alignParentRight="true"
分别替换为:?app:layout_constraintLeft_toRightOf="@id/id_btn01",app:layout_constraintRight_toRightOf="parent"


是不是觉得so easy ,但是我们看一下效果图:



?


?


?


?


?


?


是不是和预期有一定的区别,假设你将Btn02的宽度设置的非常大,你会发现更加诡异的事情:



?


?


?


?


?


?


?


你会发现Btn02,好像疯了一样,我们设置的在btn01右侧,和与parent右侧对齐完全失效了!!!


在当控件有自己设置的宽度,例如warp_content、固定值时,我们为控件添加的都是约束“Constraint”,这个约束有点像橡皮筋一样会拉这个控件,即上面内容所描述的拉力,但是并不会改变控件的尺寸(RL很明显不是这样的)。


例如上例,当btn02的宽度较小时,我们为其左侧设置了一个约束(btn01右侧),右侧设置了一个约束(parent右侧对其),当两个约束同时生效的时候(你可以认为两边都是相同的一个拉力),btn02会居中;当btn02特别大的时候,依然是这两个力,那么会发生什么?会造成左侧和右侧超出的距离一样大。


那么现在大家肯定有些疑问:怎么样才能和上面的RL一样,宽度刚好占据剩下的距离呢(btn01右侧到屏幕右侧的距离)


? ? ? ?我们刚才所有的尝试都是在控件自身拥有特定的宽度情况下执行的;那么如果希望控件的宽度根据由约束来控件,不妨去掉这个特定的宽度,即设置为0试试?对!当我们将btn02的宽度设置为0时,一切又变得很完美。



?


?


?


?


?


?


?


那么这里,你可能会问0值是什么含义,其实在ConstraintLayout中0代表含义:MATCH_CONSTRAINT,看到这个常量,是不是瞬间觉得好理解了一点。此处要注意的是MATCH_CONSTRAINT在xml页面中不被识别,该值应该直接用0来表示。
最后一个问题,MATCH_PARENT哪去了?你可以认为:在ConstraintLayout中已经不支持MATCH_PARENT这个值了,你可以通过MATCH_CONSTRAINT配合约束实现类似的效果。


好了到这里,目前我们看到其已经和RelativeLayout势均力敌了,接下来我们看一下RL做不到的特性。


二、带有合适宽高比的banner广告栏

有时候我们需要在布局顶部展示一个特定的banner图,比如宽度匹配整个父布局,并且宽高比为16:6。看到这里你的第一想法可能是引入百分比布局,那么如何在ConstraintLayout中快速便捷的实现呢?


android:id="@+id/tv_banner"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#765"
android:gravity="center"
android:text="我是16:6的导航栏"
app:layout_constraintDimensionRatio="16:6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

宽度为0dp,通过约束使其占满全局。高度为0dp,通过layout_constraintDimensionRatio定义的宽高比确定实际高度。此属性还支持另外的两种写法,有兴趣可以试试


app:layout_constraintDimensionRatio="W,16:6"
app:layout_constraintDimensionRatio="H,16:6"


三、底部的tab实现

说到底部的tab很多人会想到LinearLayout的weight权重属性,那么ConstraintLayout该如何实现呢?


android:id="@+id/tv_one"
style="@style/tv_bottom"
android:background="#f67"
android:text="Tab1"
app:layout_constraintEnd_toStartOf="@id/tv_two"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent" />

android:id="@+id/tv_two"
style="@style/tv_bottom"
android:background="#a67"
android:text="Tab2"
app:layout_constraintEnd_toStartOf="@id/tv_three"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/tv_one" />

android:id="@+id/tv_three"
style="@style/tv_bottom"
android:background="#767"
android:text="Tab3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/tv_two" />

layout_constraintHorizontal_weight类似于线性布局的权重功能。


四、展示一个不一样的悬浮球

这里我们用TextView冒充一下其中需要满足以下两个需求,
?


我相信你常用的几个布局很难单一不嵌套实现该效果。


android:layout_width="0dp"
android:layout_height="0dp"
android:background="#f91"
android:gravity="center"
android:text="我是宽度为父布局13%高度为30%的TextView"
app:layout_constraintBottom_toTopOf="@+id/tv_one"
app:layout_constraintEnd_toStartOf="@+id/tv_baseline"
app:layout_constraintHeight_percent="0.3"
app:layout_constraintHorizontal_bias="0.15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.95"
app:layout_constraintWidth_percent="0.13" />

layout_constraintWidth_percent和layout_constraintHeight_percent ?字面很容易理解,就是匹配父布局的百分比。


这里多出来了另一个属性bias,前面我们提过约束类似于拉力的效果,那我们怎么控制力的大小呢?


layout_constraintHorizontal_bias=“0.15” 即设置左右两侧间隙比例分别为15%与85%,相当于左侧提供了85N的拉力,右侧提供了15N的拉力,共同作用下实现了以上的效果。同理layout_constraintVertical_bias的效果可以去实践下。


最后还剩下两个边边角角的属性:


layout_constraintBaseline_toBaselineOf 该控件与XX控件基准线对齐


?


layout_constraintBaseline_creator ?这是一个迷之属性,creator接受整型属性值,但该属性在 1.0.0-alpha8 版本暂时未有任何作用,查看源码发现,ConstraintLayout只是对改属性值进行了接受,但是没有做任何处理,相信在后续版本会新增其功能。


五、Guideline辅助线的使用


android:id="@+id/guideline_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.65" />

android:id="@+id/guideline_v"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.65" />

android:layout_width="wrap_content"
android:layout_height="30dp"
android:background="#520"
android:gravity="center"
android:text="辅助线TextView"
app:layout_constraintStart_toEndOf="@id/guideline_v"
app:layout_constraintTop_toBottomOf="@id/guideline_h" />

orientation方向属性就不多讲了,还有缺一个属性决定辅助线的位置,以下3种任一都可以


layout_constraintGuide_begin
layout_constraintGuide_end
layout_constraintGuide_percent


begin=30dp,即可认为距离顶部30dp的地方有个辅助线,根据orientation来决定是横向还是纵向;end=30dp,即为距离底部;percent=0.8即为距离顶部80%。


好了到此基本上ConstraintLayout的常用属性就讲完了,如果有不同的见解欢迎留言交流。

相关文档

  • mac地址存储在
  • win10蓝牙卸载重装
  • 怎样煮虾好吃
  • 要分手了伤感的话
  • 张家界当地有什么特产?
  • 劳动节给闺蜜的祝福语
  • 实用的风味小吃的作文300字7篇
  • 笔记本电脑怎么按f4
  • 腾飞吧东方巨龙
  • 苹果x合约机
  • 《小小的船》教学设计(通用3篇)
  • 我给情感涂颜色
  • WGCLOUD打造极简安装监控系统
  • C语言中的return语句后面不加表达式,直接return;,返回的是什么?表示的是什么?
  • 烈士词语的相关近义词
  • 最新会议销售经理岗位职责范文
  • C++ 学习 备忘记录(二)
  • 我爱看书的朋友
  • 纪律教育学习宣传月活动总结
  • 浅谈加拿大留学生就业攻略
  • 凶猛的龙虾
  • 语文教师个人述职报告精选5篇
  • 在VC6.0下设置Unicode编译环境
  • 关于伤感爱情经典语句
  • 去漂流要注意什么
  • 最温暖的墙中考语文记叙文阅读题及答案
  • 2020年公司业务员4月工作总结范文
  • 工程项目经理岗位的具体职责
  • 广东房屋拆迁产权调换协议书
  • 起点,终点
  • 猜你喜欢

    电脑版