Constraintlayout
——约束布局,作为Jetpack的一个组件推出。今天的面试三问就是关于布局的:
-
说说constraintlayout的主要特性,为什么会设计出这一种布局?
-
说说你所了解的constraintlayout属性
-
以及这些属性的用法
说说constraintlayout的主要特性,为什么会设计出这一种布局?
ConstraintLayout
名字叫约束布局,跟
RelativeLayout
相对布局有点像,主要使用约束的方式来指定各个控件的位置和关系,但是又远远比RelativeLayout强大。
主要有三个优点
-
第一就是强大的属性,通过约束各个控件的关系。有人可能说了
Relativelayout
不也是设置各个控件的位置吗?但是ConstraintLayout功能可多了去了,可以设置比例,设置在控件中的位置,可以设置view中心的距离,还可以设置辅助线。
-
第二就是让可视化操作更加
立体方便
,以前在可视化界面操作view难免还是比较不方便,拖着拖着就变成了固定距离。
ConstraintLayout
就方便多了,设置好约束关系即可。
-
第三就是由于这些特性,大大减少了布局的嵌套,我们了解过性能优化的都知道,布局优化最大的一点就是要
减少布局嵌套
,而ConstraintLayout显然做到了这一点。
constraintlayout属性详解(仅包括Constraintlayout单独包含的属性)
-
基本位置约束 此类控件表示与其他控件或者父view的位置。
app:layout_constraintLeft_toLeftOf 代表当前组件的左边在某组件的左边,即左对齐
app:layout_constraintBottom_toBottomOf="parent" 我的底部与父view底部对齐
-
居中效果 设置位置,左边与父布局左边对齐,右边与父布局右边对齐,就会形成左右一个平局的拉力,也就居中显示与父布局了。(可以设置0dp或者match_parent代表铺满父布局)
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="match_parent"
android:layout_width="0dp"
app:layout_constraintHorizontal_bias="0.3"
通过该属性可以设置在父布局中显示的位置,按比例显示,比如0.3就代表在3/10的位置。
android:layout_width="100dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="2:1"
该属性表示控件的宽高比,按上述代码设置后,控件的高会显示为50dp。
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@id/A"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/B" />
<TextView
android:id="@id/B"
app:layout_constraintLeft_toRightOf="@+id/A"
app:layout_constraintRight_toLeftOf="@+id/C" />
<TextView
android:id="@id/C"
app:layout_constraintLeft_toRightOf="@+id/B"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
如果一个布局里面的子布局依次设置了位置约束,也就是左侧连着A,A连着B,B连着C,C连着右侧,那么由于各个面的拉力,这几个布局就会平均分布于子布局
如上一节说的,如果默认情况,三个子布局就会平局分布,也就是间隙平分了剩余空间,这种是
spread
模式,也可以通过
layout_constraintVertical_chainStyle
属性设置。另外还有两种类型:
-
spread_inside
,两边自view靠边,剩余view平分
-
packed
,子view紧挨着,并且居中显示,只有左右空隙
-
子布局分布权重
我们都知道
LinearLayout
可以设置子布局的权重,也就是设置某个view占比多少。同样
Constraintlayout
也可以。
app:layout_constraintHorizontal_weight="2"
比如上面给A设置权重为2,其他为1,宽设置为0dp,那么ABC的宽度就会按照2:1:1分布
在
Constraintlayout
中,可以画辅助线,可以理解为一个实际的view,一条线,但是不会显示。比如有个需求,是要我的view底部位置在布局的中间,那么就可以在中间画一条辅助线,然后view设置为辅助线之上位置显示即可
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@id/A"
app:layout_constraintBottom_toTopOf="@+id/guideline" />
和辅助线有点像,但是辅助线只是一个view,而Barrier可以整合多个view让其像个整体。比如有个需求,有两个textview,不知道哪个textview更长,我需要在更长的textview右边显示一个imageview,就可以把
两个textview设置为一个整体
。
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/tv1"/>
<android.support.constraint.Barrier
android:id="@+id/barrier2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="tv1,tv2"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/barrier2"/>
这个虚拟视图和
Barrier
有点不一样,
Barrier
更像一个组合辅助线,还是用来控制位置的。而Group是把多个组件圈起来一起控制,比如一起显示,一起隐藏。
<android.support.constraint.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"