码个蛋(codeegg)第 726 次推文
作者: GitCode8
原文: https://juejin.im/post/5d12c4146fb9a07ea33c24b7
前言
最近中毒很深,经常逛掘金,看到很多优秀的文章,感谢掘金。同时也看到很多标题,看看XXXX,一篇就够了。
技术一直在不停的更新迭代,看一篇永远是不够的,建议再看一遍官网的,可以看到被作者过滤掉的信息或者最新的更新。这就是我为什么会在文末放官网链接的原因,如果有的话。
ConstraintLayout
ConstraintLayout作为一款可以灵活调整view位置和大小的Viewgroup被Google疯狂推荐,以前创建布局,默认根元素都是LinearLayout, 现在是ConstraintLayout了。
ConstraintLayout能够以支持库的形式最小支持到API 9,同时也在不断的丰富ConstraintLayout的API和功能。ConstraintLayout在复杂布局中能够有效的,降低布局的层级,提高性能,使用更加灵活。
在app组件的Graldle默认都有如下依赖:
// 可能版本不一样哦
implementation 'com.android.support.constraint:constraint-layout:1.1.3
迫不及待想了解ConstraintLayout能在布局做点什么了。
2.1 相对定位
相对定位,其实这跟RelativeLayout差不多,一个View相对另外一个View的位置。
通过简单的使用ConstraintLayout的属性也就可以实现以上布局。World对于Hello的右边,GitCode对位于Hello的下边
<?xml version="1.0" encoding="utf-8"?>
...>
...
android:text="Hello"
android:id="@+id/tvHello"/>...
android:text="World"
app:layout_constraintLeft_toRightOf="@+id/tvHello"/>...
android:text="GitCode"
app:layout_constraintTop_toBottomOf="@id/tvHello"/>
以TextView World相对位置属性layout_constraintLeft_toRightOf来说,constraintLeft表示TextView World本身的左边,一个View有四条边,因此TextView的上、右、下边分别对应着constraintTop、constraintRight、constraintBottom。toRightOf则表示位于另外一个View的右边,例如此处位于Hello的右边,因此对应还有toLeftOf、toRghtOf、toBottomOf,分别位于View Hello的左、右、下边。
总结的说,constraintXXX表示View自身约束的边,toXXXOf表示另一个View的边,而XXX的值可以是Left、Top、Right、Bottom,分别对应左,上、右、下边。layout_constraintStart_toEndOf也是类似的道理。
另外需要注意的是,view的位置可以相对于同层的view和parent,在相对于parent的时候toLeftOf、toTopOf、toRghtOf、toBottomOf分别表示位于parent的内部左上右下边缘。如图:红色框表示parent view。
再来看看一个特殊的场景:
此时想要Hello和World文本中间对齐怎么办?
ConstraintLayout提供了 layout_constraintBaseline_toBaselineOf 属性。
...
android:text="Hello"
android:id="@+id/tvHello"/>...
android:text="World"
app:layout_constraintBaseline_toBaselineOf="@id/tvHello"
app:layout_constraintLeft_toRightOf="@+id/tvHello" />
此时界面就如愿了,比Relativelayout方便多了。
什么是baseline?贴张官网的图。
2.2 边距
边距与平常使用并无太大区别,但需要先确定view的位置,边距才会生效。如:
...
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"/>
在其他的ViewGroup,TextView的layout_marginTop和layout_marginLeft属性是会生效的,但在ConstraintLayout不会生效,因为此时TextView的位置还没确定。下面的代码才会生效。
...
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
常用属性如下:
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
GONE Margin
有时候,会有这种需求,在World可见的时候,GitCode与World的左边距是0,当World不见时,GitCode的左边距是某个特定的值。
World可见的效果,GitCode的左边距为0
World不可见的效果,GitCode的左边距为10
为此,ConstraintLayout提供了特殊的goneMargin属性,在目标View隐藏时,属性生效。有如下属性:
layout_goneMarginStart
layout_gon