ConstraintLayout 中 Barrier 的使用

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笔记

猜你喜欢

转载自blog.csdn.net/ShawnXiaFei/article/details/81208511