添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Android-ConstraintLayout(约束布局)-Chains链(链条布局,Nice)

到Chains这个部分了。之前的新项目做得登录,注册,重置密码等暂时还没用到这种。不过后面可能随着新的设计可能会涉及到。所以赶紧过来看看先。新项目基本就打算全部用约束布局实现了。实际用了也会越来越熟悉的。

Chain 链是一种特殊的约束让多个 chain 链连接的 Views 能够平分剩余空间位置像LinearLayout的权重,不过还扩展了很多功能。所以做权重什么的还是需要这种布局。 有点疑问?之前的Bias呢? 之前的Bias我们看下定义

The default when encountering such opposite constraints is to center the widget; but you can tweak the positioning to favor one side over another using the bias attributes:

Bias是用来做间距比例使用的,为了偏向另一边更多一点。一般我们控件如果left、right都设置了都是居中的,如果你想靠左边多一些,就可以用这个比例来设置。相对margin来讲适配更好,毕竟采用的是比例。

如果要做三个控件均匀横向排列,想想前几篇的知识能不能做? 相对布局,间距,中心布局,环形布局,尺寸相关约束 ,回过头看了看官方网站回忆了下知识,发现好像不行。貌似这种只有权重能解决这个问题了,不然没办法均分?

Chains来了,别慌....

几点要求满足链式 (看下水平情况,垂直类似分析):

1. 控件之间已经形成约束关系,parent←A← →B← →C->parent

2.Chain heads(链条头用来设置/觉得链条属性),即是A作为链条头

3.链条头、链条尾分别是A和C,了解下对后面一些属性有帮助

  • 看看怎么设置链条布局样式吧,水平垂直分别是 layout_constraintHorizontal_chainStyle和layout_constraintVertical_chainStyle, 分别三个属性


1.水平的 Chain 链的默认模式就是 spread模式 ,它将平分间隙让多个 Views 布局到剩余空间。

app:layout_constraintHorizontal_chainStyle="spread":

<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:background="@color/colorAccent">
    <Button
        android:id="@+id/sbBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="sb"
        app:layout_constraintEnd_toStartOf="@+id/sbBtn01"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/sbBtn01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="sb01"
        app:layout_constraintEnd_toStartOf="@+id/sbBtn02"
        app:layout_constraintStart_toEndOf="@+id/sbBtn"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/sbBtn02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="sb02"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/sbBtn01"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

2.水平的 Chain 链的默认模式就是 spread_inside模式 ,它将会把两边链条头、链条尾分别是A和C 到外向父组件边缘的距离去除,然后让剩余的 Views 在剩余的空间内平分间隙布局

3.水平的 Chain 链的默认模式就是 packed 模式 ,它将所有 Views 打包到一起不分配多余的间隙(当然不包括通过 margin 设置多个 Views 之间的间隙),然后将整个组件组在可用的剩余位置居中

以上三种样式基本能满足这种均分布局样式 。不过如果某个控件的宽度设置的不是wrap_content,而是一个具体的宽度dp。还比较大。这个时候布局就会有问题

   <?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:background="@color/colorAccent">
    <Button
        android:id="@+id/sbBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="sb"
        app:layout_constraintEnd_toStartOf="@+id/sbBtn01"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/sbBtn01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="sb01"
        app:layout_constraintEnd_toStartOf="@+id/sbBtn02"
        app:layout_constraintStart_toEndOf="@+id/sbBtn"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/sbBtn02"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="sb02"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/sbBtn01"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

解决:我们需要把控件的宽度都设置为 0dp , 这样能保证控件依然均分,某个控件的内容如果超出宽度也不会影响均分效果。

当然你也可以一些控件自适应wrap_content,剩下的控件0dp,这样就能保证自适应的控件内容显示正常(不换行),但是设置为0dp的控件就会被强制各种 压迫 :

So...注意结合相关知识才能应对更加复杂的情况


  • 看看权重吧...这跟 LinearLayout weight 权重设置很像, 同样也能做到和上面一样的效果,也可以多分一点给第一个控件 。不过也是需要设置宽度为0dp,否则大家都是wrap_content,就压迫的啥都看不到了...
  • app:layout_constraintHorizontal_weight ="2"
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:background="@color/colorAccent">
    <Button
        android:id="@+id/sbBtn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="sb"
        app:layout_constraintEnd_toStartOf="@+id/sbBtn01"
        app:layout_constraintHorizontal_weight="2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/sbBtn01"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="sb02sb02sb02sb02sb02sb02sb02sb02"
        app:layout_constraintEnd_toStartOf="@+id/sbBtn02"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@+id/sbBtn"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/sbBtn02"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="sb02sb02sb02sb02sb02"
        app:layout_constraintEnd_toEndOf="parent"