ConstrainLayout 基础教程3,八年Android开发心路历程

  • constraint_referenced_ids:用于设置 Barrier 所引用的控件的 ID,可同时设置多个

  • barrierAllowsGoneWidgets:默认为 true,当 Barrier 所引用的控件为 Gone 时,则 Barrier 的创建行为是在已 Gone 的控件已解析的位置上进行创建。如果设置为 false,则不会将 Gone 的控件考虑在内

下面是一个非常简单的例子:

image.png

我们有三个TextViews: 左边 textView1 和 textView2 ,右边 textView3。textView3 约束在 textView1 的右边,效果也符合我们的预期。

但是当需要支持多语言的时候事情就变得复杂了。如果我们添加德语就出现了问题,因为在英语里面textView1的文字是长于textView2的,但是在德语中却是textView2的文字比textView1长:

image.png

这里的问题在于textView3仍然是相对于textView1的,所以textView2直接插入了textView3中。在设计视图里看起来更明显(白色背景的那个)。

View只能设置一个View作为锚点,设置了一个就顾不了另一个,所以传统方法是使用TableLayout,或者把 textView1 & textView2 包裹在一个垂直的LinearLayout中,然后让textView3约束在这个LinearLayout的后面。 所以就诞生了Barrier,他可以设置N个View作为锚点。

Barrier 是一个虚拟视图,类似于 Guideline,用来约束对象。Barrier 和 Guideline 的区别在于它是由多个 view 的大小决定的。在这个例子中,我们不知道 textView1 和 textView2 哪个长些,因此我们可以 基于这两个 view 的宽度创建一个Barrier。我们可以让 textView3 约束在 Barrier 后面。

在编辑器中创建Barriers

首先选择上下文菜单的create a vertical barrier,创建一个垂直的barrier:

注:Android Studio2.3貌似没有这个菜单,Android Studio3.0有,但是在help菜单组的下级菜单,跟下面的演示图有些区别。

barrier_create.gif

你可以在组建树(component tree)中看到Barrier(左边靠近底部的面板)。

我们可以通过拖动改变它的位置(可选项):

barrier_order.gif

接下来我们需要设置Barrier 方向(direction)。这里我们是想让Barrier根据textView1 和 textView2 的大小确定是在谁的后面,因此我们需要把 direction 设置为 end:

barrier_direction.gif

最后一步是告诉Barrier它是相对于哪些view。我不用约束来形容是因为约束一般指一对一的,而这里是多个view。我们需要为 Barrier 指定引用的view的 ID , 可以通过在 component tree 中把view拖动到 Barrier 来完成:

barrier_references.gif

一旦定义好之后,这些引用将被列为 Barrier 的 children。而且你还会在蓝色面板中看到Barrier跳到了新的位置(垂直的虚线)。

现在 Barrier 就已经定义好了,只剩下把textView3的约束从相对于 textView1 改为 相对于 Barrier 了:

barrier_constrain.gif

完了之后 textView3 就到了 textView2 的后面了。

为了看到整体的效果,可以切换语言,此时你会看到 Barrier 会自动位于较宽的那个 textView 后面,也就间接让 textView3 也位于了正确的位置:

barrier_example.gif

在XML中创建Barriers

XML代码其实也非常简单:

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
android:layout_width=“match_parent”
android:layout_height=“match_parent”>

<androidx.constraintlayout.widget.Barrier
android:id=“@+id/barrier7”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
app:barrierDirection=“end”
app:constraint_referenced_ids=“textView2,textView1” />

</androidx.constraintlayout.widget.ConstraintLayout>

barrierAllowsGoneWidgets

Barrier-barrierAllowsGoneWidgets.gif

目前button3和button1 button2的top对齐,此时如果button1 Gone了呢?

如上图效果,button1 gone之后,会变为一个点,所以button3顶齐父布局也没问题。但有的时候这不符合我们的需求,我们希望Barrier不要关注Gone的View了,所以谷歌提供了属性barrierAllowsGoneWidgets,设为false后,就不在关注Gone的View了,效果如上图,button1 gone之后,button3 不再和父布局顶齐,而是和button2顶齐。

Barrier特别的地方就在于Barrier元素自身。app:barrierDirection 属性决定 Barrier 的方向 - 这里把它放在被引用view的后面。被引用的view 是布局中的view的id列表,用逗号隔开。

借用一张图 来自medium.com/androiddeve…

Barrier-demo.gif

Group

使用组,您可以将某些视图分组在一起。不要把这与Android中的普通ViewGroups混淆。ConstraintLayout中的一个组仅包含对视图ID的引用,而不将组合中的视图嵌套。这样一来,您可以设置组中控件的可见性仅通过设置组的可见性就行了,而无需设置每个视图的可见性。这对于诸如错误屏幕或加载屏幕的事情是有用的,其中一些元素需要一次更改其可见性

其可使用到的属性为:

  • constraint_referenced_ids:指定所引用控件的 id。

<androidx.constraintlayout.widget.Group
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:visibility=“gone”
app:constraint_referenced_ids=“title, desc” />

如果有多个 Group,是可以同时指定相同的控件的,最终是以 XML 中最后声明的 Group 为准。

Placeholder

Placeholder顾名思义,就是用来一个占位的东西,它可以通过 setContentId() 方法将占位符变为有效的视图。如果视图已经存在于屏幕上,那么视图将会从原有位置消失。

除此之外,还可以通过 setEmptyVisibility() 方法设置当视图不存在时占位符的可见性。

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.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:id=“@+id/constraintLayout”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=“.MainActivity”>

<androidx.constraintlayout.widget.Placeholder
android:id=“@+id/placeholder”
android:layout_width=“96dp”
android:layout_height=“96dp”
android:layout_marginStart=“8dp”
android:layout_marginTop=“8dp”
android:layout_marginEnd=“8dp”
android:layout_marginBottom=“8dp”
android:scaleType=“centerInside”
app:layout_constraintBottom_toBottomOf=“parent”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent”
app:layout_constraintTop_toTopOf=“@+id/mail” />

<ImageButton
android:id=“@+id/play”
android:layout_width=“48dp”
android:layout_height=“48dp”
android:layout_marginTop=“16dp”
android:background=“#00000000”
android:scaleType=“centerInside”
android:src=“@drawable/delete”
android:tint=“#FFA000”

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

文末

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

这里放上一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家

工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

这里放上一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家

[外链图片转存中…(img-m8gHUglb-1711744833547)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值