以往的关于ConstraintLayout
的文章都是讲解它的各种属性的用法,到底这些用法和属性怎么达到效果却说不清,只干巴巴说些属性的作用有什么用,希望直接能上手来用,因此以目标为导向,来看看这个控件如何展示它强大的功能!
说明
- 有些效果完全可以用嵌套实现,但却不能仅用一个层次的控件实现,所以可以多用
ConstraintLayout
进行视图层次的优化, 最好就是一开始直接用ConstraintLayout
不用再推到后面 - 都以水平方向作为示例,竖直方向不言自明
- 关注关键属性(代码块中的行没法标红,所以靠悟性了)
- 不对各个属性单独说明了
相对父亲居中
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
相对兄弟居中
A相对B水平居中,注意必须是平级的兄弟视图,其实就是中线对齐中线
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@+id/right"
app:layout_constraintBottom_toBottomOf="@+id/right"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/right"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBBBB"
android:textColor="#999"
android:textSize="20sp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
中线对齐中线
A的中线与B的中线对齐, 不管AB大小
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAAAA"
android:textSize="30sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/right"
app:layout_constraintBottom_toBottomOf="@+id/right"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBB"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
中线对齐边
A的中线与B的上边对齐
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAAAA"
android:textSize="30sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/right"
app:layout_constraintBottom_toTopOf="@+id/right"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBB"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
边对齐中线
A的上边与B的中线对齐(有时由于锚点的原因不能简单的与上一条相反)
这时我们需要一个辅助View了,然而并不是android.support.constraint.Guideline
参看这篇文章
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAAAA"
android:textColor="#333"
android:textSize="23sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/middle"/>
<View
android:id="@+id/middle"
android:layout_width="match_parent"
android:layout_height="0.5dp"
app:layout_constraintRight_toRightOf="@id/right"
android:visibility="invisible"
app:layout_constraintTop_toTopOf="@id/right"
app:layout_constraintBottom_toBottomOf="@id/right"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
边占比
A的右边对齐B整体宽度的30%处,不管A,B宽度变化
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAAAA"
android:textColor="#333"
android:textSize="30sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@+id/percent_30"/>
<View
android:id="@+id/percent_30"
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:visibility="invisible"
app:layout_constraintLeft_toLeftOf="@id/right"
app:layout_constraintRight_toRightOf="@id/right"
app:layout_constraintHorizontal_bias="0.3"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
整体占比
A的整体宽度占在B整体宽度的30%
<TextView
android:id="@+id/left"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:text="AAAAAAAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/right"
app:layout_constraintRight_toLeftOf="@+id/percent_30"/>
<View
android:id="@+id/percent_30"
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:visibility="invisible"
app:layout_constraintLeft_toLeftOf="@id/right"
app:layout_constraintRight_toRightOf="@id/right"
app:layout_constraintHorizontal_bias="0.3"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBBBBBBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
整体中线占比
A整体始终处于B整体宽度的30%处,不管A宽度如何变化,即A的中线对齐B的水平30%处
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/percent_30"
app:layout_constraintRight_toLeftOf="@+id/percent_30"/>
<View
android:id="@+id/percent_30"
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:visibility="invisible"
app:layout_constraintLeft_toLeftOf="@id/right"
app:layout_constraintRight_toRightOf="@id/right"
app:layout_constraintHorizontal_bias="0.3"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBBBBBBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
跟随消失
B设置为Gone,A跟随B也为Gone
这时需要用到辅助控件android.support.constraint.Group
, 同时也不是直接操作B,而且操作Group
;用Group
将两个控件绑定,设置Group
消失时两个一同消失
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<android.support.constraint.Group
android:id="@+id/group"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="left,right"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
代码处的设置为
view.findViewById(R.id.group).setVisibility(View.GONE);
视图均分
大小各自均分
<TextView
android:id="@+id/left"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:text="AAAAAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/middle"/>
<TextView
android:id="@+id/middle"
android:layout_width="0dp"
android:layout_height="60dp"
tools:text="C"
android:textColor="#999"
android:textSize="20sp"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/left"
app:layout_constraintRight_toLeftOf="@id/right"/>
<TextView
android:id="@+id/right"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:text="BBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/middle"
app:layout_constraintRight_toRightOf="parent"/>
视图间隔均分
大小各自不固定,相邻间隔均分
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/middle"/>
<TextView
android:id="@+id/middle"
android:layout_width="wrap_content"
android:layout_height="60dp"
tools:text="C"
android:textColor="#999"
android:textSize="20sp"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/left"
app:layout_constraintRight_toLeftOf="@id/right"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/middle"
app:layout_constraintRight_toRightOf="parent"/>
紧靠, 整体居中
AB紧靠,各自宽度不固定,但整体居中
单纯这种效果用LinearLayout
最简单,以下以三个视图相对父亲居中为例:(也可变成相对平级其它视图居中)
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/middle"
app:layout_constraintHorizontal_chainStyle="packed"/>
<TextView
android:id="@+id/middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="CCC"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/left"
app:layout_constraintRight_toLeftOf="@+id/right"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBBBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@+id/middle"/>
紧靠, 边居中
AB紧靠,各自宽度不固定,但相邻边居中,以平级其它视图居中为例(也可变成相对父亲居中,相对父亲居中即可用android.support.constraint.Guideline
)
@+id/back_ground
为平级其他视图,用特殊背景色标识。
问题来了:如果是3个视图要如何实现?
<View
android:id="@+id/back_ground"
android:layout_width="350dp"
android:layout_height="60dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#E6E4E4"/>
<View
android:id="@+id/middle"
android:layout_width="0.5dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="@+id/back_ground"
app:layout_constraintRight_toRightOf="@+id/back_ground"/>
<TextView
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="AAAAAAAA"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@+id/back_ground"
app:layout_constraintBottom_toBottomOf="@+id/back_ground"
app:layout_constraintRight_toLeftOf="@+id/middle"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBBBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintTop_toTopOf="@+id/back_ground"
app:layout_constraintBottom_toBottomOf="@+id/back_ground"
app:layout_constraintLeft_toRightOf="@+id/middle"/>
紧靠, 达到最大宽度后滑动
一个非常实用的效果: 比如竖直方向上的LinearLayout,当内容增加高度开始增加,但超过指定的一个值后高度(70dp)不再增加,整体内容开始滑动. 我们肯定是要借助ScrollView
的
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintHeight_max="70dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
紧靠, 动态最大宽度
说明:该效果只能为ConstraintLayout实现!
希望达到以下效果 B紧靠A,各自宽度非固定值,一旦B到达边沿A宽度不能再增长,即A有最大宽度,但其由B决定(和LinearLayout的紧靠效果有点类似但完全不同!) 即:
这种效果以往任何控件都无法以属性声明的方式实现,除非配合代码,但现在用ConstraintLayout
了之后,根本不用写代码, 爽了一啤!
展示ConstraintLayout
强大功能的时候到了,上完整代码
<android.support.constraint.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:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/left"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:text="AAAAAAAAAAAAADDDDDDD"
android:textColor="#333"
android:textSize="30sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/right"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintWidth_default="wrap"
app:layout_constraintHorizontal_bias="0"/>
<TextView
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BBB"
android:textColor="#999"
android:textSize="20sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/left"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>