学习Android的第五天

目录

Android ConstraintLayout 约束布局

简介

ConstraintLayout 约束布局分类

1、相对定位 (Relative positioning)

2、边距 ( Margins )

3、居中定位和偏向 ( Centering positioning and bias )

4、环形定位 ( Circular positioning )

5、对可见性的处理 ( Visibility behavior )

6、尺寸约束 ( Dimension constraints )

7、链 ( Chains )

8、辅助布局 ( Virtual Helpers objects )

9、比例 ( Ratio )


Android ConstraintLayout 约束布局

Android 中一些传统布局的优缺点。确实,每种布局方式都有其特定的使用场景和限制,这也是为什么在实际开发中,开发者经常需要结合多种布局方式来实现复杂的 UI 设计。

  1. AbsoluteLayout:这个布局虽然灵活,但需要对齐像素,且适配不同的设备屏幕非常困难。因此,它在实际开发中已经被弃用。
  2. LinearLayout:这是最简单、最直观的布局方式之一,但它的问题在于,当 UI 变得复杂时,嵌套的 LinearLayout 会导致布局层次过深,性能下降,且难以维护。
  3. GridLayout 和 TableLayout:这两种布局主要用于实现网格和表格样式的 UI,但它们的使用场景相对单一,不够灵活。
  4. RelativeLayout:这个布局非常灵活,可以用于实现各种复杂的 UI 设计。然而,它的灵活性也可能导致布局代码变得难以理解和维护,特别是在处理大型项目时。此外,它只能处理父子关系和兄弟关系之间的布局,这在某些情况下可能会限制其使用。

因此,结合使用 LinearLayout 和 RelativeLayout 是一种非常实用的策略。通常,开发者会使用 LinearLayout 来构建整体框架和大型组件,然后使用 RelativeLayout 来处理细节和微调布局。这样做可以充分利用两种布局的优势,同时避免它们的缺点。

不过,值得注意的是,随着 Android 开发的不断发展,现在有了更多现代的布局方式可供选择,如 ConstraintLayout。ConstraintLayout 提供了一种更为强大和灵活的布局方式,可以在不增加布局层次的情况下实现复杂的 UI 设计。因此,对于新的开发项目,使用 ConstraintLayout 可能是一个更好的选择。

简介

ConstraintLayout 是一种非常强大的布局方式,它的核心思想就是通过约束(Constraints)来定义视图(View)的位置和尺寸。这种方式旨在提供一种灵活且高效的布局解决方案,可以减少布局嵌套,优化性能,并且使得 UI 适配更加容易。

在 ConstraintLayout 中,每个视图都可以通过添加约束条件来定义其在布局中的位置。这些约束条件可以相对于父布局、其他视图或者布局的指导线(Guideline)来设置。通过设置这些约束条件,视图可以在不同的屏幕尺寸和方向下保持一致的布局效果。

ID 和 parent 是 ConstraintLayout 中非常重要的概念。每个视图都有一个唯一的 ID,用于在布局中唯一标识该视图。而 parent 则是指视图所在的父布局,通过设置与父布局的约束关系,可以定义视图在父布局中的位置。

总的来说,ConstraintLayout 是一种非常强大和灵活的布局方式,它可以帮助开发者更加高效地实现复杂的 UI 设计,并且优化布局性能。虽然它的学习曲线可能稍微陡峭一些,但是一旦掌握了它的基本用法和高级功能,就可以大大提高开发效率和布局质量。

ConstraintLayout 约束布局分类

我们知道 ConstraintLayout 也是一种约束布局,而约束的方式则有以下几种

1、相对定位 (Relative positioning)

相对定位是ConstraintLayout中最基本的功能之一,允许开发者通过指定一个组件相对于另一个组件或父布局的位置(如上、下、左、右)来确定其位置。这类似于RelativeLayout,但ConstraintLayout提供了更多的灵活性和更精确的控制。

下面是对可用约束的属性的简要说明及其应用:

水平方向约束

  • layout_constraintLeft_toLeftOf: 控件的左边缘与另一个控件的左边缘对齐。
  • layout_constraintLeft_toRightOf: 控件的左边缘与另一个控件的右边缘对齐。
  • layout_constraintRight_toLeftOf: 控件的右边缘与另一个控件的左边缘对齐。
  • layout_constraintRight_toRightOf: 控件的右边缘与另一个控件的右边缘对齐。
  • layout_constraintStart_toEndOf: 控件的起始边缘与另一个控件的结束边缘对齐。这在支持从右到左语言(如阿拉伯语)的布局中特别有用。
  • layout_constraintStart_toStartOf: 控件的起始边缘与另一个控件的起始边缘对齐。
  • layout_constraintEnd_toStartOf: 控件的结束边缘与另一个控件的起始边缘对齐。
  • layout_constraintEnd_toEndOf: 控件的结束边缘与另一个控件的结束边缘对齐。

垂直方向约束

  • layout_constraintTop_toTopOf: 控件的顶边缘与另一个控件的顶边缘对齐。
  • layout_constraintTop_toBottomOf: 控件的顶边缘与另一个控件的底边缘对齐。
  • layout_constraintBottom_toTopOf: 控件的底边缘与另一个控件的顶边缘对齐。
  • layout_constraintBottom_toBottomOf: 控件的底边缘与另一个控件的底边缘对齐。

特殊约束

  • layout_constraintBaseline_toBaselineOf: 控件的文本基线与另一个控件的文本基线对齐。这对于确保位于同一水平线上的文本视觉上保持一致非常有用,即使它们的大小或字体样式不同。

在ConstraintLayout中,所有的约束属性都遵循layout_constraintXXX_toYYYOf的命名规则,其中XXX代表目标控件自身的某一边(或基线),而YYY代表参照控件的相应边。通过这种方式,开发者可以定义组件间的相对位置关系,从而构建出复杂且灵活的布局结构。

范例

<?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="match_parent"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是 Button1"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是 button2"
        app:layout_constraintLeft_toRightOf="@id/button1"/>

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:text="我是 button3"
        app:layout_constraintBottom_toBottomOf="parent"/>
    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:text="我是 button4"
        app:layout_constraintTop_toBottomOf="@id/button1"/>

</androidx.constraintlayout.widget.ConstraintLayout>

运行范例,显示结果如下 

2、边距 ( Margins )

边距用于在组件之间或组件与父布局之间添加空间。在ConstraintLayout中,可以很容易地为任何方向(上、下、左、右)设置边距,以创建更加美观和实用的UI设计。

margin 和以往的使用一致,注意 margin 不能为负值 即可。

边距属性

  1. android:layout_marginStart: 控件开始边(在LTR(从左到右)语言环境中为左边,在RTL(从右到左)语言环境中为右边)的外边距。用于定义控件开始边与相邻对象之间的距离。
  2. android:layout_marginEnd: 控件结束边(在LTR语言环境中为右边,在RTL语言环境中为左边)的外边距。用于定义控件结束边与相邻对象之间的距离。
  3. android:layout_marginLeft: 控件左边的外边距。不考虑语言环境,始终指向物理左边。
  4. android:layout_marginTop: 控件顶部的外边距。用于定义控件顶部与其上方对象之间的距离。
  5. android:layout_marginRight: 控件右边的外边距。不考虑语言环境,始终指向物理右边。
  6. android:layout_marginBottom: 控件底部的外边距。用于定义控件底部与其下方对象之间的距离。

注意事项

  • 值必须是大于等于0的数值,并且带上单位,如dp(密度无关像素),sp(用于字体的缩放独立像素)等。通常,为了保证布局在不同屏幕密度上的一致性,建议使用dp作为边距的单位。
  • 在支持RTL的应用中,推荐使用layout_marginStart和layout_marginEnd而非layout_marginLeft和layout_marginRight,以确保布局在从左到右和从右到左的语言环境中都表现正确。

连接到 GONE (缺失) 小部件时的边距

在使用ConstraintLayout进行Android布局设计时,处理GONE状态的控件与其他控件之间的约束关系是一个常见的需求。当一个控件被设置为GONE状态时,它不仅不会在界面上显示,也不会占用任何布局空间。然而,在某些情况下,开发者可能希望即使控件处于GONE状态,仍然保留一定的空间或者对其他控件的位置产生影响。这时,就可以使用layout_goneMargin属性来实现这一需求。

layout_goneMargin属性

  • layout_goneMarginStart: 当约束的目标控件处于GONE状态时,当前控件的开始边距(在LTR语言环境中为左边,在RTL语言环境中为右边)。
  • layout_goneMarginEnd: 当约束的目标控件处于GONE状态时,当前控件的结束边距(在LTR语言环境中为右边,在RTL语言环境中为左边)。
  • layout_goneMarginLeft: 当约束的目标控件处于GONE状态时,当前控件的左边距。
  • layout_goneMarginTop: 当约束的目标控件处于GONE状态时,当前控件的顶边距。
  • layout_goneMarginRight: 当约束的目标控件处于GONE状态时,当前控件的右边距。
  • layout_goneMarginBottom: 当约束的目标控件处于GONE状态时,当前控件的底边距。

注意事项

  • 使用layout_goneMargin属性可以在控件消失时维护布局的整体外观和结构,但应谨慎使用,以避免布局过于复杂或出现意料之外的布局行为。
  • 这些属性只有在ConstraintLayout中有效,因为它们是ConstraintLayout特有的功能。

范例

<?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="match_parent"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/signin"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="我是 Button1"
        app:layout_constraintEnd_toEndOf="parent" />


    <Button
        android:id="@+id/signup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="10dp"
        android:text="我是 Button2"
        app:layout_constraintEnd_toStartOf="@id/signin"
        app:layout_goneMarginEnd="110dp"/>

    <Button
        android:id="@+id/forgot_password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是 Button3"
        android:layout_marginTop="20dp"
        app:layout_constraintTop_toBottomOf="@id/signup"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_goneMarginStart="50dp" />

    <Button
        android:id="@+id/help"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是 Button4"
        android:layout_marginTop="20dp"
        app:layout_constraintTop_toBottomOf="@id/forgot_password"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_goneMarginEnd="50dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

运行范例,显示结果如下 

 

3、居中定位和偏向 ( Centering positioning and bias )

居中定位允许开发者将组件在其父布局或两个其他组件之间居中对齐。偏向是ConstraintLayout的一个独特特性,它允许开发者调整组件在居中位置的偏向程度,从而实现更灵活的布局设计。

居中定位

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

倾向 ( Bias ) 提供了两个属性用于设置偏向到的程度

属性说明
layout_constraintHorizontal_bias(0最左边 1 最右边,默认是 0.5)
layout_constraintVertical_bias(0最上边 1 最底边,默认是 0.5)

注意:偏向值都是 0.5,表示组件完全居中。 

在 ConstraintLayout 中,可以使用居中定位和偏向来实现灵活的布局设计。下面是一个简单的示例,演示如何在 ConstraintLayout 中使用居中定位和偏向:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="居中文本视图"
        android:textSize="24sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintVertical_bias="0.5"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

运行范例,显示结果如下 

4、环形定位 ( Circular positioning )

环形定位是ConstraintLayout提供的一个有趣的特性,允许开发者基于另一个组件的位置以圆形方式定位组件。这可以用来创建动态且吸引人的界面。

使用这个布局,需要修改 build.gradle 文件添加如下代码

dependencies {
    compile ("com.android.support.constraint:constraint-layout:1.1.0-beta3")
}

 环形定位 (Circular positioning) 在 ConstraintLayout 中是一种非常有用的布局方式,它允许你约束一个视图相对于另一个视图的弧度和半径进行定位。这在一些布局和动画效果中非常有用,比如模拟行星绕太阳旋转的效果。

以下是 ConstraintLayout 提供的用于环形定位的属性:

  • layout_constraintCircle:引用另一个小部件的 ID,该小部件将作为参考点,用于确定环形定位的中心。
  • layout_constraintCircleRadius:指定到其它小部件中心的距离,即半径。
  • layout_constraintCircleAngle:指定小部件应处于的角度,以度数表示,范围从0到360度。

需要注意的是,环形定位是以各自视图的中心为参照进行约束的,与通常使用 start/end/top/bottom 或 baseline 进行约束的方式不同。

下面是一个简单的示例,演示如何使用环形定位:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="Button A" />

    <Button
        android:id="@+id/buttonB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button B"
        app:layout_constraintCircle="@+id/buttonA"
        app:layout_constraintCircleRadius="100dp"
        app:layout_constraintCircleAngle="45" />
</androidx.constraintlayout.widget.ConstraintLayout>

运行范例,显示结果如下

5、对可见性的处理 ( Visibility behavior )

对可见性的处理 ( Visibility behavior ) 是对 goneMargin 的补充。

对于 ConstraintLayout 中设置为 View.GONE 的视图,会被解析为一个点,并且会忽略设置的 margin。这意味着,即使视图设置为 GONE,它仍然会在布局计算中占据空间,但它的实际尺寸被视为零,并且不会对布局本身造成影响。具体来说,有以下几个特点:

  • 对于布局传递,GONE 视图的尺寸被视为零,因此它们不会占据任何可见空间。
  • 如果 GONE 视图对其他视图有约束力(例如,作为约束的目标),则这些约束仍然会被尊重,但任何 margin 都将被视为 0。
  • 任何 GONE 视图的 margin 都会被忽略,即使它们是其他视图的 margin。

这种布局行为在制作动画时非常有用,因为即使将视图临时标记为 GONE,也不会破坏原有的布局。这使得在动画期间可以动态隐藏或显示视图,而不会影响布局的稳定性。

这种特定行为的布局处理在 ConstraintLayout 中非常灵活,并且可以帮助开发者实现复杂的布局和动画效果。

范例

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="单击我"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="隐藏文本//显示文本"
        android:textSize="18sp"
        app:layout_constraintStart_toEndOf="@id/button"
        app:layout_constraintTop_toTopOf="@id/button"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ViewAnimator;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        TextView textView = findViewById(R.id.textView);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (textView.getVisibility() == View.VISIBLE) {
                    textView.setVisibility(View.GONE);
                } else {
                    textView.setVisibility(View.VISIBLE);
                }
            }
        });

    }
}

 这段代码在按钮上设置了点击事件监听器,当按钮被点击时,检查文本视图的可见性。如果文本视图当前是可见的,则将其设置为 View.GONE,这样它就会被隐藏。如果文本视图当前是隐藏的,则将其设置为 View.VISIBLE,这样它就会重新显示。

通过这种方式,我们可以在 ConstraintLayout 中使用 View.GONE 来动态隐藏或显示视图,而不会影响到布局的稳定性。

6、尺寸约束 ( Dimension constraints )

尺寸约束是ConstraintLayout中的一个核心概念,允许开发者定义组件的最小、最大尺寸,或者根据其他组件的尺寸来动态调整尺寸。这为创建响应式布局提供了极大的灵活性。

ConstraintLayout 的最小和最大尺寸

  • android:minWidth:设置布局的最小宽度。
  • android:minHeight:设置布局的最小高度。
  • android:maxWidth:设置布局的最大宽度。
  • android:maxHeight:设置布局的最大高度。

当 ConstraintLayout 的尺寸设置为 wrap_content 时,会自动考虑这些最小和最大尺寸的限制。

控件尺寸约束

1、确定尺寸:可以直接为控件指定确定的尺寸。

2、wrap_content:让控件根据其内容自适应尺寸。

3、0dp:使用 MATCH_CONSTRAINT,控件的尺寸将根据与其它控件的约束来动态调整。

  • 可以设置左/右或顶部/底部约束条件来定义相对于父布局的尺寸。
  • 如果设置了 margin,会在计算中考虑它们。

注意:在 ConstraintLayout 中,MATCH_PARENT 不再被推荐使用,而是推荐使用 MATCH_CONSTRAINT 加上相应的约束条件来定义相对于父布局的尺寸。

范例

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:text="Button1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/button10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2"
        app:layout_constraintLeft_toLeftOf="@+id/button"
        app:layout_constraintRight_toRightOf="@+id/button"
        app:layout_constraintTop_toBottomOf="@+id/button"/>


    <Button
        android:id="@+id/button12"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="Button3"
        app:layout_constraintLeft_toLeftOf="@id/button10"
        app:layout_constraintRight_toRightOf="@id/button10"
        app:layout_constraintTop_toBottomOf="@id/button10"/>

    <Button
        android:id="@+id/button11"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="Button4"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button12"/>

</androidx.constraintlayout.widget.ConstraintLayout>

运行范例,显示结果如下 

 

7、链 ( Chains )

链是ConstraintLayout中用于将多个组件链接在一起的机制,可以视为一种高级的相对定位。通过链,可以轻松实现复杂的布局结构,如等分空间、权重分配等。

链条

在 ConstraintLayout 中,可以使用链条(Chains)来为一组 UI 控件提供类似群组的统一表现,其中在一个方向上(水平或垂直)连接的视图称为链条。链条可以帮助你在布局中创建一组相关的视图,并且可以在另一个轴上单独控制它们的位置。

1、创建链条:

如果一组 UI 控件通过双向连接(即彼此约束)连接在一起,则将它们视为链条。以下是创建链条的示例:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 2"
        app:layout_constraintStart_toEndOf="@id/button1"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 3"
        app:layout_constraintStart_toEndOf="@id/button2"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

在这个示例中,Button1、Button2、Button3 通过 app:layout_constraintStart_toEndOf 和 app:layout_constraintTop_toTopOf 相互连接,形成了一个水平链条。

2、链条头:

在链条中,最左边的视图或者最顶部的视图被认为是链条的头。在水平链条中,最左边的视图是头,而在垂直链条中,最顶部的视图是头。

3、链条上的 margin:

如果链条中的某个视图设置了 margin,这些 margin 会被考虑在内,并影响到链条的布局。

链条样式 ( Chain Style )

在 ConstraintLayout 中,可以通过设置属性 layout_constraintHorizontal_chainStyle 或 layout_constraintVertical_chainStyle 来调整链条的样式。以下是这两个属性的可用值及其说明:

水平链样式 (layout_constraintHorizontal_chainStyle) 和垂直链样式 (layout_constraintVertical_chainStyle):

  • CHAIN_SPREAD:元素将被展开,这是默认的样式。在 spread 模式下,如果某些小部件设置为 MATCH_CONSTRAINT,则它们将拆分可用空间。
  • CHAIN_SPREAD_INSIDE:类似于 CHAIN_SPREAD,但链的端点将不会扩展。这意味着链的第一个和最后一个元素将保持在链的范围内,不会延伸到父布局的边界。
  • CHAIN_PACKED:链的元素将被打包在一起。子控件的水平或垂直偏移属性将影响打包元素的定位。这样,所有的链条元素将会聚集在一起,形成一个紧凑的组。

下面是一个示例,演示如何使用链条样式属性:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 使用 CHAIN_SPREAD_INSIDE 样式的水平链条 -->
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 2"
        app:layout_constraintStart_toEndOf="@id/button1"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 3"
        app:layout_constraintStart_toEndOf="@id/button2"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

在这个示例中,三个按钮通过水平连接形成了一个链条,并且使用了 app:layout_constraintHorizontal_chainStyle="spread_inside" 属性来设置链条样式为 CHAIN_SPREAD_INSIDE。这意味着链的端点不会扩展,而是链中的元素会在链的范围内进行分布。

加权链 ( Weighted chains )

在 ConstraintLayout 中,可以使用 layout_constraintHorizontal_weight 和 layout_constraintVertical_weight 属性来实现加权链(Weighted chains),类似于 LinearLayout 中的 weight。加权链的默认行为是在可用空间中平均分配元素。如果一个或多个元素使用 MATCH_CONSTRAINT,它们将使用剩余的空白空间,这些空间在它们之间相等。

layout_constraintHorizontal_weight 和 layout_constraintVertical_weight 属性:

  • 这两个属性用于决定设置了 MATCH_CONSTRAINT 的 View 如何分配空间。
  • 它们的值决定了每个元素相对于其他元素在链中所占的权重。

以下是一个示例,演示如何使用加权链的属性:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 使用加权链的水平链条 -->
    <Button
        android:id="@+id/button1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintHorizontal_weight="1"
        />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 2"
        app:layout_constraintStart_toEndOf="@id/button1"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintHorizontal_weight="2"
        />

    <Button
        android:id="@+id/button3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 3"
        app:layout_constraintStart_toEndOf="@id/button2"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintHorizontal_weight="1"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

在这个示例中,三个按钮通过水平连接形成了一个链条,并且每个按钮都设置了 layout_constraintHorizontal_weight 属性来指定它们的权重。按钮2的权重为2,而按钮1和按钮3的权重为1。因此,在布局过程中,可用的空间将按照2:1:1的比例分配给按钮1、按钮2和按钮3,以实现加权分配的效果。

8、辅助布局 ( Virtual Helpers objects )

辅助布局对象,如Guideline、Barrier等,是ConstraintLayout提供的用于辅助布局的虚拟视图。它们不会在应用的UI中显示,但可以作为布局中的参考点或边界,帮助实现更复杂的布局需求。

在 ConstraintLayout 中,可以使用 Guideline 辅助布局来帮助定位其他视图,它是一个不可见的工具类,仅用于辅助布局而不会被显示。

Guideline 可以是水平或垂直的,可以通过设置 android:orientation 属性来指定。例如,android:orientation="vertical" 表示垂直的 Guideline。

定位 Guideline 有三种方式:

  • 指定距离左侧或顶部的固定距离:使用 layout_constraintGuide_begin 属性可以将 Guideline 定位到距离左侧或顶部的固定距离。
  • 指定距离右侧或底部的固定距离:使用 layout_constraintGuide_end 属性可以将 Guideline 定位到距离右侧或底部的固定距离。
  • 指定在父控件中的宽度或高度的百分比:使用 layout_constraintGuide_percent 属性可以将 Guideline 定位到父控件中的宽度或高度的百分比位置。

以下是一个示例,演示如何使用 Guideline 辅助布局:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 垂直 Guideline,距离左侧固定距离为 50dp -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="50dp"
        />

    <!-- 水平 Guideline,距离顶部固定距离为 100dp -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="100dp"
        />

    <!-- 在父控件宽度的 25% 处创建一个垂直 Guideline -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline_vertical_percent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.25"
        />
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="Button1"
        app:layout_constraintStart_toStartOf="@id/guideline_vertical"
        app:layout_constraintTop_toTopOf="@id/guideline_horizontal"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

 在这个示例中,创建了三个 Guideline。第一个是垂直的 Guideline,距离左侧固定距离为 50dp;第二个是水平的 Guideline,距离顶部固定距离为 100dp;第三个是垂直的 Guideline,定位在父控件宽度的 25% 处。

还有一个示例视图,是一个 Button,通过设置其约束将其定位在第一个垂直 Guideline 的左侧和第二个水平 Guideline 的顶部。这样,Guideline 可以辅助将视图定位到特定位置。

9、比例 ( Ratio )

在 ConstraintLayout 中,可以使用 app:layout_constraintDimensionRatio 属性来设置某个方向的比例约束。以下是一些关于这个属性的说明:

app:layout_constraintDimensionRatio 属性:

  • 约束比例:用逗号 , 分隔方向,用冒号 : 分隔比例。
  • 只有一个方向约束:如果只有一个方向的约束,可以用比例去定义 View 的宽高。需要将至少一个约束维度设置为 0dp(即 MATCH_CONSTRAINT),并将属性 app:layout_constraintDimensionRatio 设置为给定的比例。
  • 当约束多于一个 ( 宽高都被约束了):在 ConstraintLayout 中,如果两个维度均设置为 MATCH_CONSTRAINT(即 0dp),也可以使用比例来约束宽高。在这种情况下,系统会使用满足所有约束条件和比率的最大尺寸。如果需要根据一个维度的尺寸去约束另一个维度的尺寸,则可以在比率值的前面添加 W 或者 H 来分别约束宽度或者高度。

范例

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 只有一个方向约束,使用比例约束设置 View 的宽高 -->
    <TextView
        android:id="@+id/textViewSingleConstraint"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Single Constraint with Ratio"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintDimensionRatio="2:1"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="16dp"
        android:background="#2196F3"
        android:textColor="#FFFFFF"
        android:gravity="center"
        />

    <!-- 宽高都被约束,使用比例约束设置 View 的宽高 -->
    <TextView
        android:id="@+id/textViewBothConstraints"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Both Constraints with Ratio"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textViewSingleConstraint"
        app:layout_constraintDimensionRatio="H,4:3"
        android:layout_marginTop="16dp"
        android:background="#4CAF50"
        android:textColor="#FFFFFF"
        android:gravity="center"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

运行范例,显示结果如下 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/375459.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Compose 一个音视频APP——Magic Music Player

Magic Music APP Magic Music APP Magic Music APP概述效果预览-视频资源功能预览Library歌曲播放效果预览歌曲播放依赖注入设置播放源播放进度上一首&下一首UI响应 歌词歌词解析解析成行逐行解析 视频播放AndroidView引入Exoplayer自定义Exoplayer样式横竖屏切换 歌曲多任…

vscode远程连接失败

目录 解决方案尝试1解决方案尝试2 解决方案尝试1 最近通过vscode一直使用腾讯云的服务器作为远程开发环境&#xff0c;以前一直很好用。 直到最近重装了系统之后&#xff0c;发现vscode没法对云服务器进行连接了&#xff0c;即使在远程主机添加了本地的公钥也不行。直接报错:…

156基于Matlab的光纤陀螺随机噪声和信号

基于Matlab的光纤陀螺随机噪声和信号&#xff0c;利用固定步长和可调步长的LMS自适应滤波、最小二乘法、滑动均值三种方法进行降噪处理&#xff0c;最后用阿兰方差评价降噪效果。程序已调通&#xff0c;可直接运行。 156 信号处理 自适应滤波 降噪效果评估 (xiaohongshu.com)

redis:七、集群方案(主从复制、哨兵模式、分片集群)和面试模板

redis集群方案 在Redis中提供的集群方案总共有三种&#xff08;一般一个redis节点不超过10G内存&#xff09; 主从复制哨兵模式分片集群 主从复制&#xff08;主从数据同步&#xff09; replid和offset Replication Id&#xff1a;简称replid&#xff0c;是数据集的标记&a…

Oracle Vagrant Box 扩展根文件系统

需求 默认的Oracle Database 19c Vagrant Box的磁盘为34GB。 最近在做数据库升级实验&#xff0c;加之导入AWR dump数据&#xff0c;导致空间不够。 因此需要对磁盘进行扩容。 扩容方法1&#xff1a;预先扩容 此方法参考文档Vagrant, how to specify the disk size?。 指…

硬件工程师大师之道-EMC设计与诊断整改笔记1

什么是EMC EMC实质指的是多种用电设备在同一空间里同时工作时能够遵守“和平共处”的“多边主义”所谓你好我好大家好。 EMC包含EMS与EMI两个部分。 EMS: 任何用电设备在工作时都能通过空间合或者通过与其他设备的连接线&#xff0c;接收到四周的电磁波或者干扰电压电流&#…

代码随想录第28天|● 93.复原IP地址 ● 78.子集 ● 90.子集II

文章目录 93.复原IP地址思路&#xff1a;切割问题代码&#xff1a; 78.子集思路-找所有节点coding: 90.子集II思路-去重 93.复原IP地址 思路&#xff1a;切割问题 代码&#xff1a; 使用stringBuilder&#xff0c;故优化时间、空间复杂度&#xff0c;因为向字符串插入字符时无…

VScode为什么选择了Electron,而不是QT?

选择Electron而不是QT可能是基于以下几个原因&#xff1a; Web技术的普及和开发者生态系统&#xff1a;Web技术如HTML、CSS和JavaScript在开发者中非常普及&#xff0c;开发者生态系统庞大且活跃。使用Electron可以利用这些熟悉的Web技术和丰富的开发者社区资源。跨平台支持&am…

CS50x 2024 - Lecture 1 - C

本周学习C语言&#xff0c;重点是函数、变量、条件语句和循环。 05:11介绍了编程语言的转换过程&#xff0c;从源代码到机器码&#xff0c;以及编译器的作用。 编译器是将一种语言翻译成另一种语言的程序 09:18使用CS50.dev进行编程&#xff0c;介绍了VS Code和命令行界面的…

Cpp-2

类与对象 /*类与对象&#xff1a;1.类是一种用户自定义的数据类型&#xff08;函数&#xff0c;数据&#xff09;2.类是具有相同的属性和行为的对象的集合3.类是对象的抽象&#xff0c;对象是类的具体4.对象&#xff1a;通过使用类类型定义的变量 */定义类 /*如何定义类&…

JRT监听程序

本次设计避免以往设计缺陷&#xff0c;老的主要为了保持兼容性&#xff0c;在用的设计就不好调了。 首先&#xff0c;接口抽象时候就不在给参数放仪器ID和处理类了&#xff0c;直接放仪器配置实体&#xff0c;接口实现想用什么属性就用什么属性&#xff0c;避免老方式要扩参数时…

软件安全测试报告如何编写?权威的安全测试报告如何获取?

软件安全测试报告是一份详尽的文件&#xff0c;它主要通过对软件进行全面、系统的测试&#xff0c;评估软件的安全性&#xff0c;并在测试结束后起草编写的报告。该报告能清晰地展示出软件的各项安全风险以及潜在威胁&#xff0c;为用户提供安全方面的决策依据&#xff0c;并帮…

PMP考试成绩如何查询?

PMP考试成绩已经陆续出来了&#xff0c;出成绩时间大概一周左右&#xff0c;没收到的别着急&#xff0c;先把如何查询成绩路径弄清楚。 【如何查询成绩】 1、输入网址&#xff08;PMI官网&#xff0c;不知道网址的私戳&#xff09;&#xff0c;点击 Log In 如果忘记 PMI 的账…

如何在Windows系统上部署docker

上次在Windows系统上部署成功Ubuntu系统&#xff0c;这次准备在Windows上部署docker desktop应用 这个应用软件类似于虚拟机&#xff0c;可以在该应用软件上部署多个镜像容器。其最直观的表现就是可以借用Windows和Ubuntu终端来访问docker“模拟的系统”。 Docker简介 Docke…

JAVA建造者模式详解

建造者模式 1 建造者模式介绍 建造者模式 (builder pattern), 也被称为生成器模式 , 是一种创建型设计模式. 定义: 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 **建造者模式要解决的问题 ** 建造者模式可以将部件和其组装过程分开…

cesium系列篇:Entity vs Primitive 源码解析(从Entity到Primitive)02

上篇文章中&#xff0c;我们介绍了使用viewer.entities.add添加entity之后的信号传递以及最后entity对象被传递到GeometryVisualizer&#xff1b; 这篇文章&#xff0c;我们则介绍如何在逐帧渲染的过程中根据GeometryVisualizer中的entity对象创建相应的primitive 这是下文中…

正点原子--STM32通用定时器学习笔记(2)

1. 通用定时器输入捕获部分框图介绍 捕获/比较通道的输入部分&#xff08;通道1&#xff09; 采样频率&#xff1a;控制寄存器 1(TIMx_CR1)的CKD[1:0] ⬇⬇⬇​​​​​​​滤波方式选择&#xff1a; 捕获/ 比较模式寄存器 1(TIMx_CCMR1)的输入捕获部分⬇​​​​​​​⬇​…

机器人工具箱学习(一)

一、机器人工具箱介绍 机器人工具箱是由来自昆士兰科技大学的教授Peter Corke开发的&#xff0c;被广泛用于机器人进行仿真&#xff08;主要是串联机器人&#xff09;。该工具箱支持机器人一些基本算法的功能&#xff0c;例如三维坐标中的方向表示&#xff0c;运动学、动力学模…

pwn旅行之[WUSTCTF 2020]getshell2(一些小知识)

题目分析1 首先打开这个题目的链接的时候&#xff0c;看到了ret2syscall&#xff0c;以为是一个纯正的syscall的题&#xff0c;结果&#xff0c;做的时候发现这个题的危险函数限制的字符串个数不足以写入syscall需要的所有地址&#xff0c;所以&#xff0c;这里参考dalao们的方…

时光峰峦文物璀璨,预防性保护筑安全

在璀璨的历史长河中&#xff0c;珍贵文物如同时间的印记&#xff0c;承载着过往的辉煌。《人文山水时光峰峦——多彩贵州历史文化展》便是这样一场文化的盛宴&#xff0c;汇聚了众多首次露面的宝藏。然而&#xff0c;文物的保存对环境要求极为苛刻&#xff0c;温湿度波动都可能…