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分布
- 虚拟视图辅助线Guideline
在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" />
- 虚拟视图Barrier
和辅助线有点像,但是辅助线只是一个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"/>
- 虚拟视图Group
这个虚拟视图和Barrier
有点不一样,Barrier
更像一个组合辅助线,还是用来控制位置的。而Group是把多个组件圈起来一起控制,比如一起显示,一起隐藏。
<android.support.constraint.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="tv1,tv2"/>
- 圆形定位
Constraintlayout
还可以设置相对于view的中心点进行位置摆放,主要涉及到三个属性:
layout_constraintCircle :引用另一个view的ID
layout_constraintCircleRadius :到其他view中心的距离
layout_constraintCircleAngle :应该处于view哪个角度(以度为单位,从0到360)