TableLayout 默认情况下有个特性,就是不论第一列长短,第二列总能对齐,就像下面这个样子:
因此当有类似需求时,总会第一时间想到 TableLayout。
但是 TableLayout 使用的时候,需要嵌套至少3层,如果需求再复杂些,嵌套层数可能会更多,这样对布局的绘制无疑也是一种负担。
那么功能强大的 ConstraintLayout 是否可以做到这种效果呢?当然可以!
Barrier 的简单介绍
在知道怎么用 ConstraintLayout 实现这个需求之前,需要先了解一个辅助类,也就是:
android.support.constraint.Barrier
官方说这个类是用来辅助布局的,它不参与视图的绘制。
我们先了解一下它是如何不参与绘制的:
public class Barrier extends ConstraintHelper
可以看到它继承自 ConstraintHelper,而 ConstraintHelper 继承自 View,而且没有实现 onDraw:
public abstract class ConstraintHelper extends View {
······
public void onDraw(Canvas canvas) {
}
······
}
确实没有参与绘制,诚不欺我!
另外,Barrier 是用多个 View 作为限制源来决定自身位置的一种辅助线,它有两个比较重要的属性:
1、barrierDirection
,取值有top、bottom、left、right、start、end
,用于控制 Barrier 相对于给定的 View 的位置。比如在上面的栗子中,Barrier 应该在 Title 的右侧,因此这里取值right(也可end,自行琢磨)。
2、constraint_referenced_ids
,取值是要依赖的控件的id
(不需要@+id/
)。Barrier 将会使用ids中最大的一个的宽(高)作为自己的位置。
一张很不形象的草图:
需求实现
有了上面的基础后,就可以着手写布局了。先确定左边两个 TextView 的位置,然后让 Barrier 依赖于这两个 TextView 并在它们在右侧,最后让右边两个 TextView 依赖于 Barrier 即可。
完整的布局代码如下:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题:"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这里是内容:"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTitle" />
<TextView
android:id="@+id/tvTitleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你真是标题?"
android:textSize="18sp"
app:layout_constraintStart_toEndOf="@+id/barrier2"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvContentText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="马东什么?"
android:textSize="18sp"
app:layout_constraintStart_toEndOf="@+id/barrier2"
app:layout_constraintTop_toBottomOf="@+id/tvTitleText" />
<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="tvTitle,tvContent" />
</android.support.constraint.ConstraintLayout>
布局预览效果如下:
可以看到,相比TableLayout,ConstraintLayout实现同样的效果,布局层级只有一层,简洁了很多。
补充
1、在通过 GUI 调整 Barrier 时,往往会自动添加属性:
tools:layout_editor_absoluteX="xxdp"
此时会导致布局提示有错误:
This view is not constrained horizontally: at runtime it will jump to the left unless you add a horizontal constraint…
这时只需要删除自动添加的属性即可。(Barrier 的定位只需要 constraint_referenced_ids
,其它的不需要)
2、在设置 constraint_referenced_ids 时,也可以通过拖拽的形式完成,就像这个样子:
此笔记已同步推送到微信公众号:灰灰的Rom笔记