ConstraintLayout - 拓展,以及一些藏在其中的小技巧

介绍一些自己使用到的小 trick

上一篇关于 ConstraintLayout 的文章 ConstraintLayout - 初探,以及为什么 中,我列举了几个自己在日常使用 ConstraintLayout 时候发现的一些小技巧。我觉得,即使是作为系列文章中最简单的一篇,直接翻译文档,列举 ConstraintLayout 的基本属性,感觉也没有太多意义,所以就跳过了对基本属性的介绍,直接列举了自己感觉需要理解的 Tips。

本文是计划中关于 ConstraintLayout 系列文章的第二篇。计划与第一篇的写法会有些类似,会用具体的例子作为案例,介绍 ConstraintLayout 中的工具类属性,以及会列举一些可以用 ConstraintLayout 轻易解决的需求[^1]

直接来看具体的场景吧!

问题一:怎么实现负 margin 的效果?

这是前几天在 Telegram 群组中有人的提问,具体想实现的效果如下图所示:

image.png

想要实现的效果是,

item 底部的那个文本如果是单行文本,就跟图片底部对齐;如果是多行文本就换行,但是多行的第一行底部位置还是跟 image 的底部对齐

我在看到图的时候就感觉,这是一个很适合用 ConstraintLayout 来实现的布局。原因有二: - 这里的布局是会随着子 view 的情况相对进行调整的; - 这里的变化情况,完全可以用子 view 之间的约束关系来进行精准描述。

主要需要解决的是 ImageView 和最底下 TextView 之间的位置关系。这里 ImageView 类似于定位的锚,TextView 对准的是 ImageView 底部偏上一些的位置,即 TextView 的 top 应该与 ImageView 底部的某个位置对齐。这里我采用的方法是,在 ImageView 的底部另外有一个 Space 控件,高度与一行 TextView 的高度一致,Space 控件的 bottom 和 ImageView 的 bottom 对齐。同时,让 TextView 的 top 和 Space 的 top 对齐,这样就实现了设计图中想要的效果。相关的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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="wrap_content"
    android:padding="16dp"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/img"
        android:layout_width="40dp"
        android:layout_height="60dp"
        android:src="@color/colorPrimaryDark"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is text 1"
        android:layout_marginLeft="16dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toEndOf="@id/img"
        />

    <Space
        android:id="@+id/dummy"
        android:layout_width="wrap_content"
        android:layout_height="15dp"
        app:layout_constraintBottom_toBottomOf="@id/img"
        app:layout_constraintStart_toEndOf="@id/img"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginLeft="16dp"
        android:text="This is text 2 \n with new line"
        app:layout_constraintTop_toTopOf="@id/dummy"
        app:layout_constraintStart_toEndOf="@id/img"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

实现的效果如图:

image.png

如果不用 ConstraintLayout 的话,其他实现的办法也肯定存在。但用 ConstraintLayout 的思想来思考问题,觉得自然而且流畅。

问题二:来写一个自适应的 Grid 列表吧

这是我自己想的一个小题目,之前用在实习生面试的题目里头。想实现的效果如图:

image.png

未完待续

[^1]:言下之意是,可以用 ConstraintLayout 轻易解决,但要用其他的方法可能要多费一些功夫。