Constraint Layout 约束布局基础使用

简介: Constraint Layout 约束布局基础使用

Android 设备在运行,具有不同的尺寸和目标,如手机、平板电脑、电视、汽车、嵌入式硬件等,Android UI 已成为 Android 用户和开发人员非常有影响力的部分。随着构建复杂 UI 的新兴需求,google为了更好的解决适配问题,提供出来ConstraintLayout 约束布局。

为什么要约束布局?

在 Constraint Layout 之前,Android UI 是由线性布局、Frame Layout 和 RelativeLayout 等几个 View Group 创建的。在 Android 开发历史中,这些布局在创建 UI 时非常有用。嵌套是 Android 开发人员经常处理的主要问题之一——尤其是在使用上述布局时。这不仅会使布局文件变大而难以理解,而且还会影响 UI 渲染的性能。

ConstraintLayout是 Android 团队新发布的 View Group,它解决了嵌套和性能等问题。这不仅可以帮助开发人员构建更复杂和更大的 UI,而且还带有扁平的层次结构。本系列文章将借助真实的 UI 示例逐步解释 ConstraintLayout 中的所有功能;

在项目中添加 ConstraintLayout

要在项目中使用 ConstraintLayout,请将库作为依赖项添加到应用级build.gradle文件中。如果您的项目已经具有依赖项,则这不是必需的。

implementation "androidx.constraintlayout:constraintlayout:$constraintVersion"

添加约束

设置依赖项后,您可以ConstraintLayout通过添加如下代码来添加:


      <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_60">
            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/on_car_guide"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_begin="@dimen/dp_130" />
            <TextView
                android:id="@+id/textView"
                android:layout_width="@dimen/dp_70"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/dp_10"
                android:text="扫描区"
                android:textColor="@color/color_333"
                android:textSize="@dimen/sp_16"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
            <androidx.appcompat.widget.AppCompatEditText
                android:id="@+id/scan_area_view"
                style="@style/CommonEditStyle"
                android:layout_width="0dp"
                android:layout_height="@dimen/dp_40"
                android:hint="请扫描或输入"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/btn_scan_enter"
                app:layout_constraintLeft_toRightOf="@id/on_car_guide"
                app:layout_constraintRight_toLeftOf="@id/btn_scan_enter"
                app:layout_constraintStart_toEndOf="@+id/textView"
                app:layout_constraintTop_toTopOf="parent" />
            <Button
                android:id="@+id/btn_scan_enter"
                style="@style/CommonButtonStyle"
                android:layout_width="@dimen/dp_65"
                android:layout_height="@dimen/dp_40"
                android:layout_marginEnd="@dimen/dp_10"
                android:backgroundTint="@color/color_34c"
                android:text="确定"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>


    视图和小部件(例如按钮、文本等)被添加到 ConstraintLayout 标签内,然后成为所有嵌套元素的父级。在上面的代码中,设备的屏幕作为 ConstraintLayout 的父级。

    在约束布局中,每个视图有四个边,称为锚点(看下图中的圆圈),这些锚点 作为约束的源或目标操作

    要定义视图的位置,我们必须为其添加至少一个水平约束和一个垂直约束要设置视图的水平垂直位置,您需要使用 ConstraintLayout 中提供的一些约束。

    这些约束的编写如下图所示。请注意,Source 和 Target 是一些视图,例如按钮、复选框等。您可以使用任何其他视图的 ID 或父视图来引用这些约束。根布局的父级将是设备本身,在嵌套布局的情况下,父级将是包含该特定视图的布局。

    layout_constraintTop_toTopOf

    这个约束告诉源视图的顶部应该与目标视图的顶部相同。如下图所示,绿色和蓝色视图的顶层位于相同的垂直位置。

    layout_constraintBottom_toBottomOf

    这个约束告诉源视图的底部应该与目标视图的底部相同。如下图所示,绿色和蓝色视图的底层处于相同的垂直位置。

    layout_constraintBottom_toTopOf

    这个约束告诉源视图的底部应该与目标视图的顶部相同。如下图所示,底层的绿色视图和顶层的蓝色视图处于相同的垂直位置。

    layout_constraintTop_toBottomOf

    这个约束告诉源视图的顶部应该与目标视图的底部相同。如下图所示,顶层的绿色视图和底层的蓝色视图处于垂直位置

    layout_constraintStart_toStartOf

    这个约束告诉源视图的开始应该与目标视图的开始相同。如下图所示,绿色和蓝色视图的起始层位于垂直位置。

    layout_constraintEnd_toEndOf

    这个约束告诉源视图的结束应该与目标视图的结束相同。如下图所示,绿色末端层和蓝色末端层视图处于垂直位置。

    layout_constraintEnd_toStartOf

    这个约束告诉源视图的结束应该与目标视图的开始对齐。如下图所示,绿色的结束层和蓝色视图的开始层位于垂直位置。


    layout_constraintStart_toEndOf

    这个约束告诉源视图的开始应该与目标视图的结束对齐。如下图所示,绿色的起始层和蓝色视图的结束层位于垂直位置。

      <?xml version="1.0" encoding="utf-8"?>
      <androidx.constraintlayout.widget.ConstraintLayout 
          android:id="@+id/container" 
          android:layout_width="fill_parent" 
          android:layout_height="fill_parent"
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">
          <androidx.appcompat.widget.AppCompatImageView 
              android:id="@+id/bg_login" 
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent"
              android:src="@drawable/icon_bg_login"
              android:scaleType="centerCrop" 
              app:layout_constraintBottom_toBottomOf="parent" 
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
          <androidx.appcompat.widget.AppCompatImageView android:id="@+id/bg_login_logo"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="76.0dip"
              android:scaleType="centerCrop"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
          <EditText android:id="@+id/password"
              android:visibility="gone"
              android:layout_width="200.0dip"
              android:layout_height="wrap_content"
              android:hint="输入密码"
              android:selectAllOnFocus="true"
              android:inputType="textPassword"
              android:imeOptions="actionDone"
              android:imeActionLabel="t"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
          <FrameLayout android:id="@+id/status_bar"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
          <TextView android:textSize="12.0sp"
              android:textColor="@color/white"
              android:gravity="center"
              android:id="@+id/buttonXianGuang"
              android:background="@drawable/icon_xianguang"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="17.0dip"
              android:text="先逛逛"
              android:layout_marginEnd="9.0dip"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintTop_toBottomOf="@+id/status_bar" />
          <LinearLayout android:orientation="vertical"
              android:id="@+id/edit_layout"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              app:layout_constraintBottom_toTopOf="@+id/reader">
              <LinearLayout android:gravity="center_vertical"
                  android:background="@drawable/icon_bg_edittext"
                  android:layout_width="fill_parent"
                  android:layout_height="54.0dip"
                  android:layout_marginLeft="30.0dip"
                  android:layout_marginRight="30.0dip"
                  android:layout_marginBottom="10.0dip"
                  app:layout_constraintBottom_toTopOf="@+id/login">
                  <TextView android:textSize="18.0sp"
                      android:textStyle="bold" android:textColor="#ffffffff"
                      android:gravity="center" android:id="@+id/city_select"
                      android:layout_width="wrap_content"
                      android:layout_height="fill_parent"
                      android:layout_marginLeft="25.0dip"
                      android:text="+86"
                      android:drawableRight="@drawable/ic_round_arrow_drop_down_24" />
                  <View android:background="#ffbbbbbb"
                      android:layout_width="1.0dip"
                      android:layout_height="30.0dip"
                      android:layout_marginLeft="12.0dip" />
                  <EditText android:textSize="24dp"
                      android:textColor="@color/white"
                      android:gravity="center_vertical" android:id="@+id/username"
                      android:background="@null" android:layout_width="0.0dip"
                      android:layout_height="fill_parent" android:layout_marginLeft="20.0dip"
                      android:hint="输入邮箱" android:maxLines="1"
                      android:singleLine="true" android:selectAllOnFocus="true"
                      android:layout_weight="1.0" android:inputType="phone" />
                  <ImageView android:id="@+id/button_clear" android:visibility="gone"
                      android:layout_width="18.0dip" android:layout_height="18.0dip"
                      android:layout_marginRight="20.0dip"
                      android:src="@drawable/icon_clear_text" />
              </LinearLayout>
              <com.google.android.material.button.MaterialButton android:enabled="false"
                  android:textSize="16.0sp"
                  android:textColor="@color/white"
                  android:id="@+id/login"
                  android:layout_width="fill_parent"
                  android:layout_height="54.0dip"
                  android:layout_marginLeft="30.0dip"
                  android:layout_marginRight="30.0dip"
                  android:layout_marginBottom="12.0dip"
                  android:text="确定"
                  android:insetTop="0.0dip"
                  android:insetBottom="0.0dip"
                  app:backgroundTint="@null"
                  app:cornerRadius="27.0dip"
                  app:layout_constraintBottom_toTopOf="@+id/reader"
                  app:layout_constraintEnd_toEndOf="parent"
                  app:layout_constraintStart_toStartOf="parent"
                  app:rippleColor="@null"
                  style="@style/Widget.MaterialComponents.Button.UnelevatedButton" />
          </LinearLayout>
          <LinearLayout android:gravity="center"
              android:orientation="horizontal"
              android:id="@+id/reader"
              android:paddingTop="10.0dip"
              android:paddingBottom="10.0dip"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_marginBottom="12.0dip"
              app:layout_constraintBottom_toTopOf="@+id/phone_one_login">
              <com.google.android.material.checkbox.MaterialCheckBox 
                  android:id="@+id/imageCheck" 
                  android:background="@drawable/icon_unchecked_reader" 
                  android:layout_width="18.0dip" 
                  android:layout_height="18.0dip" 
                  android:checked="false"
                  android:button="@null" />
              <TextView android:textSize="10.0sp" 
                  android:textColor="@color/white" 
                  android:id="@+id/agreementText" 
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content" 
                  android:layout_marginLeft="6.0dip" 
                  android:text="我已阅读并同意《用户协议》《隐私协议》" />
          </LinearLayout>
          <LinearLayout android:gravity="center_horizontal" 
              android:orientation="horizontal"
              android:id="@+id/phone_one_login" 
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" 
              android:layout_marginBottom="39.0dip" 
              app:layout_constraintBottom_toTopOf="@+id/other_login_title">
              <TextView android:textSize="14.0sp" 
                  android:textColor="#ff999999"
                  android:layout_width="wrap_content" 
                  android:layout_height="wrap_content"
                  android:layout_marginBottom="10.0dip" 
                  android:text="手机号码一键登录" 
                  android:drawableRight="@drawable/icon_arrow_right"
                  android:drawablePadding="2.0dip" />
          </LinearLayout>
          <LinearLayout android:gravity="center" 
              android:orientation="horizontal" 
              android:id="@+id/other_login_title" 
              android:layout_width="fill_parent" 
              android:layout_height="wrap_content"
              android:layout_marginBottom="20.0dip" 
              app:layout_constraintBottom_toTopOf="@+id/weixinLogin">
              <View android:id="@+id/line1" 
                  android:background="@color/a_module_login_white30"
                  android:layout_width="30.0dip" 
                  android:layout_height="1.0dip" />
              <TextView android:textSize="10.0sp" 
                  android:textColor="@color/a_module_login_white30" 
                  android:id="@+id/text2" 
                  android:layout_width="wrap_content" 
                  android:layout_height="wrap_content" 
                  android:layout_marginLeft="10.0dip" 
                  android:layout_marginRight="10.0dip"
                  android:text="其他方式登录" />
              <View android:id="@+id/line3" 
                  android:background="@color/a_module_login_white30" 
                  android:layout_width="30.0dip" 
                  android:layout_height="1.0dip" />
          </LinearLayout>
          <FrameLayout android:id="@+id/loading"
              android:background="@drawable/a_module_login_loading_bg"
              android:visibility="gone"
              android:layout_width="80.0dip"
              android:layout_height="80.0dip" 
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent">
              <ProgressBar android:layout_gravity="center"
                  android:id="@+id/progressBar"
                  android:layout_width="35.0dip" 
                  android:layout_height="35.0dip"
                  android:indeterminateDrawable="@drawable/a_module_login_progressbar_style"
                  android:indeterminateBehavior="repeat"
                  app:indicatorColor="@color/white"
                  app:trackColor="#ff999999" />
          </FrameLayout>
          <androidx.appcompat.widget.AppCompatImageView 
              android:id="@+id/weixinLogin"
              android:layout_width="36.0dip"
              android:layout_height="36.0dip"
              android:layout_marginBottom="39.0dip"
              android:src="@drawable/icon_weixin" 
              app:layout_constraintBottom_toTopOf="@+id/navigationBar"
              app:layout_constraintEnd_toStartOf="@+id/qqLogin"
              app:layout_constraintHorizontal_chainStyle="packed" 
              app:layout_constraintStart_toStartOf="parent" />
          <androidx.appcompat.widget.AppCompatImageView 
              android:id="@+id/qqLogin"
              android:layout_width="36.0dip" 
              android:layout_height="36.0dip" 
              android:layout_marginLeft="29.0dip" 
              android:layout_marginBottom="39.0dip" 
              android:src="@drawable/icon_qq" 
              app:layout_constraintBottom_toTopOf="@+id/navigationBar" 
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toEndOf="@+id/weixinLogin" />
          <FrameLayout android:id="@+id/navigationBar" 
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" 
              app:layout_constraintBottom_toBottomOf="parent" 
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent" />
      </androidx.constraintlayout.widget.ConstraintLayout>

      640.png


      以上是具体实现的一个约束布局文件,主要是对几个属性的掌握,没什么难点之处,主要是多写多使用。

      相关文章
      |
      6月前
      |
      数据可视化 Android开发
      Android布局——约束布局
      Android布局——约束布局
      |
      6月前
      |
      前端开发 搜索推荐 容器
      div+css的布局较table布局有什么优缺点?
      div+css的布局较table布局有什么优缺点?
      |
      Android开发 容器
      Android 实现控件对称布局(约束布局和线性布局)
      画界面时会遇到很多界面上的布局,虽然很简单,但是每次做起来不熟练,总结一下一些日常的
      |
      前端开发
      table布局的一些总结
      table-layout作用就是让表格布局固定,使表格的宽度不会根据内容多少而动态变化。
      163 0
      table布局的一些总结
      |
      API Android开发
      布局之ConstraintLayout 约束布局
      布局之ConstraintLayout 约束布局
      141 0
      布局之ConstraintLayout 约束布局
      |
      XML 编解码 开发工具
      Layout Inspector 支持 3D 视图了!
      Layout Inspector 支持 3D 视图了!
      Layout Inspector 支持 3D 视图了!
      【约束布局】ConstraintSet 约束集 ( 简介 | 约束属性集合 | 约束集初始化 | 约束集应用到布局中 | 关键帧动画 | TransitionManager 使用 )(二)
      【约束布局】ConstraintSet 约束集 ( 简介 | 约束属性集合 | 约束集初始化 | 约束集应用到布局中 | 关键帧动画 | TransitionManager 使用 )(二)
      461 0
      【约束布局】ConstraintSet 约束集 ( 简介 | 约束属性集合 | 约束集初始化 | 约束集应用到布局中 | 关键帧动画 | TransitionManager 使用 )(二)
      【约束布局】ConstraintLayout 13 种相对定位属性组合 ( 属性组合 | 用法说明 )(一)
      【约束布局】ConstraintLayout 13 种相对定位属性组合 ( 属性组合 | 用法说明 )(一)
      223 0
      【约束布局】ConstraintLayout 13 种相对定位属性组合 ( 属性组合 | 用法说明 )(一)
      |
      Android开发
      【约束布局】ConstraintLayout 13 种相对定位属性组合 ( 属性组合 | 用法说明 )(二)
      【约束布局】ConstraintLayout 13 种相对定位属性组合 ( 属性组合 | 用法说明 )(二)
      540 0
      【约束布局】ConstraintLayout 13 种相对定位属性组合 ( 属性组合 | 用法说明 )(二)
      【约束布局】ConstraintLayout 之 Chains 链式约束 ( Chains 简介 | 代码 及 布局分析 | 链头设置 | 间距设置 | 风格设置 | 权重设置 )(二)
      【约束布局】ConstraintLayout 之 Chains 链式约束 ( Chains 简介 | 代码 及 布局分析 | 链头设置 | 间距设置 | 风格设置 | 权重设置 )(二)
      1149 0
      【约束布局】ConstraintLayout 之 Chains 链式约束 ( Chains 简介 | 代码 及 布局分析 | 链头设置 | 间距设置 | 风格设置 | 权重设置 )(二)