Android ConstraintLayout 约束布局详解

Android ConstraintLayout 约束布局详解

早在2016年的Google I/O大会上 ,提出的一个可以灵活控制子控件的位置和大小的新布局。并且其号称可以实现布局最大程度的扁平化。Google 发布了Android Studio 2.2预览版,同时也发布了Android 新的布局方案 ConstraintLayout , 但是最近的一年也没有大规模的使用。2017年Google发布了 Android Studio 2.3 正式版,在 Android Studio 2.3 版本中新建的Module中默认的布局就是 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="wrap_content"
    tools:context=".Main3Activity">

    
</androidx.constraintlayout.widget.ConstraintLayout>

在使用 ConstraintLayout 的布局方案,需要在 build.gradle 引入支持库:

dependencies {
    compile 'com.android.support.constraint:constraint-layout:1.0.1'
}

为什么要使用ConstraintLayout?

上面的定义也透露出重要的信息,那就是可以实现最大程度几乎完全的扁平化。我们知道项目中的布局嵌套问题对我们的项目性能有着不小的威胁。布局能实现扁平化的话会让软件性能得到很大的提升。所以我们在开发过程中都会尽量避免布局嵌套现象,但是一些复杂的显示效果必须要嵌套才能显示(PS:可以使用merge标签,自定义布局,比较麻烦)。这就有个矛盾。下面列举几点来表明ConstraintLayout是如何能解决这个矛盾,它的强大之处。

  1. Constraint Layout可以在不嵌套view group的情况下实现非常庞大、复杂的布局。实现扁平化。
  2. Constraint Layout同时具有Relative Layout和Linear Layout的优点、特性。功能强大。
  3. 使用Constraint Layout来布局时性能要比其他布局方式高。性能比较具体参考官方文档 :
    ConstraintLayout性能优势解析-官文
  4. Constraint Layout无论是通过布局管理器拖拽,鼠标控制的形式实现还是使用XML代码去写,都比较方便。这里推荐下郭霖大神的文章,通过布局管理器拖拽的方式去实现布局的。本文说明的是通过代码的形式实现的布局效果。
    拖拽方式来使用ConstraintLayout

https://developer.android.google.cn/training/constraint-layout

另外,ConstraintLayout 还有一个优点,它可以有效地解决布局嵌套过多的问题。我们平时编写界面,复杂的布局总会伴随着多层的嵌套,而嵌套越多,程序的性能也就越差。ConstraintLayout则是使用约束的方式来指定各个控件的位置和关系的,它有点类似于 RelativeLayout,但远比RelativeLayout要更强大。

ConstraintLayout向下兼容 API 9

关于 ConstraintLayout 的基本使用方法请参照郭神的博客: 
http://blog.csdn.net/guolin_blog/article/details/53122387

说说 LinearLayout 和 RelativeLayout

说到布局的时候就会条件性的想到LinearLayout线性步局RelativeLayout相对布局。我们知道,在measure过程。RelativeLayout由于其特性是measure两次的,而LinearLayout是正常情况下只measure一次,非正常情况下呢(也不算非正常~)就是使用weight权重的情况下,LinearLayout会对没有使用weight属性的控件做第一次measure,然后再对使用过weight属性的控件做第二次measure。综合来看使用LinearLayout性能上来说比RelativeLayout好些。所以系统的decorview他就是使用的LinearLayout,上面是标题栏下面是内容ContentView。那系统使用LinearLayout却给我们MainActivity推荐RelativeLayout布局呢?这是因为,RelativeLayout由于其特性,使用它来布局的话,更方便实现扁平化,或者说更贴近扁平化。也就是说,在官方看来,实现扁平化对提升性能的帮助更大。
 

常用方法总结

layout_constraintTop_toTopOf       // 将所需视图的顶部与另一个视图的顶部对齐。 

layout_constraintTop_toBottomOf    // 将所需视图的顶部与另一个视图的底部对齐。 

layout_constraintBottom_toTopOf    // 将所需视图的底部与另一个视图的顶部对齐。 

layout_constraintBottom_toBottomOf // 将所需视图的底部与另一个视图的底部对齐。 

layout_constraintLeft_toTopOf      // 将所需视图的左侧与另一个视图的顶部对齐。 

layout_constraintLeft_toBottomOf   // 将所需视图的左侧与另一个视图的底部对齐。 

layout_constraintLeft_toLeftOf     // 将所需视图的左边与另一个视图的左边对齐。 

layout_constraintLeft_toRightOf    // 将所需视图的左边与另一个视图的右边对齐。 

layout_constraintRight_toTopOf     // 将所需视图的右对齐到另一个视图的顶部。

layout_constraintRight_toBottomOf  // 将所需视图的右对齐到另一个的底部。

layout_constraintRight_toLeftOf    // 将所需视图的右边与另一个视图的左边对齐。

layout_constraintRight_toRightOf   // 将所需视图的右边与另一个视图的右边对齐。

偏移比例

layout_constraintHorizontal_bias  //控件的水平偏移比例

layout_constraintVertical_bias   //控件的垂直偏移比例

基线约束控键

layout_constraintBaseline_toBaselineOf

以上控件属性介绍我们根据相对位置(Relative Position)

我们通过ConstraintLayout来实现下面的一个效果:

Android 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:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/got"
        android:layout_width="100dp"
        android:layout_height="120dp"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="6dp"
        android:scaleType="fitXY"
        android:src="@drawable/got"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="4dp"
        android:text="权利的游戏第八季(更新中)"
        android:textColor="#000"
        android:textSize="18sp"
        app:layout_constraintLeft_toRightOf="@+id/got"
        app:layout_constraintTop_toTopOf="@+id/got" />

    <TextView
        android:id="@+id/rating"
        android:layout_width="50dp"
        android:layout_height="20dp"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:text="评分"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/item_title"
        app:layout_constraintTop_toTopOf="@+id/got" />

    <TextView
        android:id="@+id/score"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        android:layout_marginLeft="5dp"
        android:gravity="center"
        android:text="3.3"
        app:layout_constraintBottom_toBottomOf="@+id/rating"
        app:layout_constraintLeft_toRightOf="@+id/rating"
        app:layout_constraintTop_toTopOf="@+id/rating" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="集数:6"
        android:textColor="@android:color/darker_gray"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/got"
        app:layout_constraintLeft_toLeftOf="@+id/item_title" />

    <ImageView
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:layout_marginEnd="15dp"
        android:layout_marginRight="15dp"
        android:src="@drawable/player"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Android ConstraintLayout 约束布局详解

现在我们来解读下上面的代码是如何实现这种效果的。首先我们看到了ImageView中的:

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"

这两行代码,这两行代码就是控制我们布局中控件的位置的,几乎每个控件都有,这个属性的字面意思很好理解,约束控件的左边在“parent”的左边,约束控件的上边在“parent”的上边。其实也就是约束控件的左边,上边和‘parent’的左边,上边对齐的意思。
那“parent”是什么呢?顾名思义,在这里就是ConstraintLayout。表示他的父布局。所以这两行代码也就控制了控件的位置:在ImageView位于布局的左上角。

下面再分析一下view id为item_title的TextView中使用。

app:layout_constraintLeft_toRightOf="@+id/got"
app:layout_constraintTop_toTopOf="@+id/got"

这两句的意思是,约束控件的左边在view id为photo的view的右边,约束控件的上边与view id为photo的view的上边对齐。
通过这两次的分析,大家可以细细体会一下。

 

总结

通过上面对ConstraintLayout的特性介绍,我们发现ConstraintLayout的确实很强大,有能力实现扁平化的极致。他融合了RelativeLayout和LinearLayout的优点,比如相对位置,weight chains。并且他又多出来很多RelativeLayout和LinearLayout不具备的优点。所以说ConstraintLayout的掌握还是很有必要的。书到用时方恨少,纸上得来终觉浅。祝君好运。

参考文献

https://developer.android.google.cn/training/constraint-layout

https://developer.android.com/reference/android/support/constraint/Guideline.html
https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#CenteringPositioning
http://blog.csdn.net/lmj623565791/article/details/78011599?utm_source=tuicool&utm_medium=referral

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115020.html原文链接:https://javaforall.net

(0)
上一篇 2021年10月1日 上午8:00
下一篇 2021年10月1日 上午9:00


相关推荐

  • 三极管原理及特性分析

    三极管原理及特性分析在看这篇文章之前请务必确保掌握 PN 结 二极管原理详解与应用中的内容对于三极管的符号 PNP 和 NPN 的区别等基础知识这里不做讲解文章目录 1 原理 1 原理先以 NPN 三极管为例 图中集电极电子应该画少点 掺杂少 尺寸应画高些 体积大 不易发热 后面会有说明基极和发射极正偏 所以发射极的电子会扩散到基极 由于集电极和基极 PN 结反偏 其耗尽区增大 方向为 N gt P 的电场增大 此时增大电压不像正常浓度掺杂的 PN 结一样随着电压增大而漂移电流几乎不变 因为基极的掺杂很少且很薄 所以扩散到基极的

    2026年3月26日
    2
  • RPM卸载 (Linux 使用)[通俗易懂]

    RPM卸载 (Linux 使用)[通俗易懂]可以先用rpm-q’xxx’或者rpm-qf’xxx/bin/xxxx.xx’来查询一下所属的rpm包的名字。然后用rpm-e’xxxxxx’来删之。’xxx/bin/xxxx.xx’是一个包中任意的文件’xxxxxx’是查询得到的rpm包的名称rpm-e的时候后面的文件名不用加版本号详细说明:安全地卸载RPM卸载软件包,并不是简单地将原来安

    2025年11月18日
    9
  • 大模型实操与API调用 | 二十一、讯飞星火API申请与使用指南

    大模型实操与API调用 | 二十一、讯飞星火API申请与使用指南

    2026年3月14日
    3
  • @SpringBootApplication_springboot启动类作用

    @SpringBootApplication_springboot启动类作用Args作用传递参数的一种方式;例如启动的时候java-jar–spring.profiles.active=prod或者更改自己的自定义配置信息;使用方式是–key=value它的信息优先于项目里面的配置;我们现在大部分项目都是用SpringBoot进行开发的,一般启动类的格式是SpringApplication.run(SpringBootDemoPropertiesApplication.class,args);但是好像平常一直也没有用到args;也没有穿过参数

    2025年9月8日
    6
  • aop 实现原理_简述aop的原理

    aop 实现原理_简述aop的原理概述:最近在开发中遇到了一个刚好可以用AOP实现的例子,就顺便研究了AOP的实现原理,把学习到的东西进行一个总结。文章中用到的编程语言为kotlin,需要的可以在IDEA中直接转为java。这篇文章将会按照如下目录展开:AOP简介 代码中实现举例 AOP实现原理 部分源码解析1.AOP简介相信大家或多或少的了解过AOP,都知道它是面向切面编程,在网上搜索可以找到很多的解释。…

    2026年1月19日
    4
  • 微生物组-宏基因组分析第8期 (报名直播课免费参加线下课2020.7,最后一周)

    微生物组-宏基因组分析第8期 (报名直播课免费参加线下课2020.7,最后一周)“福利公告:为了响应学员的学习需求,经过易生信培训团队的讨论筹备,现决定安排扩增子16S分析、宏基因组、Python课程和转录组的线上直播课。报名参加线上直播课的老师可在1年内选择参加同…

    2022年6月10日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号