介绍ConstrainLayout
ConstraintLayout
1.为什么用ConstraintLayout
1.1 减少嵌套,加速界面渲染
ConstraintLayout的基本使用方式就是这些, 兼顾LinearLayout与RelativeLayout的优点, 非常适合构建复杂布局, 降低布局的层级, 优化布局,加快渲染速度。
1.2 提供很多约束属性多,开发效率高
ConstraintLayout的属性有很多,有很多种约束属性, 熟悉之后可以高效完成界面搭建。
1.3 有助于界面的适配
传统Layout经常会遇到界面在不同机型界面不统一的问题,ConstraintLayout可以配合一些辅助控件像GuideLine
的百分比(app:layout_constraintGuide_percent="0.5"
)来对屏幕的水平和竖直方向做分割,在利用ConstraintLayout的属性对控件进行约束,可以达到让界面适配的效果。
2.ConstraintLayout入门
2.1 常用约束
公式:
1
| layout_constraint[本源控件要做约束位置]_to[目标控件相对的位置]="[目标控件ID]"
|
本源控件要做约束位置与目标控件的相对位置不能是随意的,是要在同一个方向上的位置,例如Bottom_toBottomOf
,Top_toBottomOf
, Bottom_toTopOf
,Top_toTopOf
是垂直方向上的一组约束,没有Top_toStart
这样的约束。
垂直方向有三个约束位置:Top, Bottom, BaseLine
水平方向有两个约束位置:Start(Left), End(Right)
可用的约束,可以搭配layout_[位置]
做一些基础和复杂的布局:
1 2 3 4 5 6 7 8 9 10 11 12 13
| layout_constraintLeft_toLeftOf layout_constraintLeft_toRightOf layout_constraintRight_toLeftOf layout_constraintRight_toRightOf layout_constraintTop_toTopOf layout_constraintTop_toBottomOf layout_constraintBottom_toTopOf layout_constraintBottom_toBottomOf layout_constraintBaseline_toBaselineOf layout_constraintStart_toEndOf layout_constraintStart_toStartOf layout_constraintEnd_toStartOf layout_constraintEnd_toEndOf
|
2.2 居中
ConstraintLayout的居中是个比较不明显的功能,水平方向的居中,要对居中的控件start(left)
和end(right)
两个位置做好约束,垂直方向的居中要对控件top
和bottom
两个位置做约束就可以达到控件在约束区域的居中效果。如下
1 2 3 4 5 6 7 8 9
| <ImageView android:id="@+id/imageView2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:layout_width="117dp" android:layout_height="143dp" app:srcCompat="@drawable/icon_android_bg"/>
|
2.3 match_parent要用0dp来替代
ConstraintLayout中de控件如果宽高要设置成match_parent
需要设置成0dp
(官方建议,也可以设置成match_parent,但是有些情况下match_parent会不生效)。设置成0dp
也需要配合相对方向的约束。
1 2 3 4 5 6 7
| <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="64dp" android:text="注册" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/>
|
2.4一些高级用法
1.GONE与Margin
有可能会遇到一个情况是,目标控件有可能会被设置为GONE
,这时候约束还是存在,界面有可能会产生不整齐的问题,这时候就可以用layout_goneMargin
来重新设置margin。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:text="BTN1" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="BTN2" app:layout_constraintStart_toStartOf="@id/button1" app:layout_constraintTop_toBottomOf="@id/button1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="50dp" android:text="BTN3" app:layout_constraintStart_toEndOf="@id/button2" app:layout_constraintTop_toTopOf="@id/button2" />
|
button2设置GONE后,约束还在,btn3与左边间距还是50,导致界面不美观:
1 2 3 4 5 6 7 8 9
| <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="50dp" //在Button设置goneMarginStart表示左边控件Gone掉的话采用新的margine app:layout_goneMarginStart="0dp" android:text="BTN3" app:layout_constraintStart_toEndOf="@id/button2" app:layout_constraintTop_toTopOf="@id/button2" />
|
2.Chain链式(主要是为了替代LinearLayout)
有一种情况是需要等分显示布局,一般用的是LinearLayout,在ConstraintLayout里面主要是要用Chain来完成平分。各个布局之前都要做一个相对的约束。即各个布局之间都要做相互的约束。
A与B做水平的平分,则A与B要做相互约束就能产生Chain:
1 2 3 4 5 6 7 8
| start_toStartOf="parent" end_toStartOf="B" //对B约束 start_toEndOf="A" //对A约束 end_toEndOf="parent"
|
并且可以通过layout_constraintHorizontal_chainStyle
或者layout_constraintVertical_chainStyle
在平分的第一个控件设置水平或者垂直方向上Chain的方式:
3.GuideLine
GuideLine主要是可以创建一条基准线,用来做一个百分比,或者固定值的控件,用法有很多,在适配上面有好的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <android.support.constraint.Guideline android:id="@+id/guideline_v" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.6"/> <com.botasky.cyberblack.view.ScanView android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="@id/guideline_v"/>
|
上面的GuideLine就可以让自定义View,ScanView(或者其他的原生控件和自定义View)的height不管在任何屏幕下所占的高度都是主屏幕的60%。与传统的写死高度相比,用GuideLine可以让适配方案不在变得复杂。
ConstraintLayout上手建议
1.尽量不要用手托控件去对控件做约束,而是用纯手打的方式去写约束
AndroidStudio的手托控件功能很鸡肋,没有像Xcode的XIB那样强大,手托控件造成的一个问题是你可能会不理解Constraint的约束原理,并且手托控件会造成IDE生成一些让人琢磨不透的代码。
2.协同开发AndroidStuido版本要统一
开发过程中遇到过因为AndroidStudio版本不统一导致其他的开发队员拉取代码后出现XML代码会自动删除一些margin的代码,并且生成一些没有意义的布局代码,导致在低版本下面布局会错乱的问题。建议开发中把IDE升级到AndroidStudio3.0,对ConstraintLayout的支持会比较稳定。并且将ConstraintLayout的版本升到最新,目前最新版本是1.1.0-beta3
。
1 2 3 4 5 6 7 8
| <ImageView android:id="@+id/imageView2" android:layout_width="117dp" android:layout_height="143dp" app:srcCompat="@drawable/icon_android_bg" //生成的无意义的代码 tools:layout_editor_absoluteX="122dp" tools:layout_editor_absoluteY="312dp" />
|