android五种布局局限性,android ConstraintLayout布局从入门到放弃

2023-10-27

布局优化是性能优化的一个方向点,包括了根据需求应该选用哪种布局容器、ViewStub懒加载,如何减少布局层级等,今天我们要探讨的就是如何使用ConstraintLayout来优化我们的布局层级。

dc2398485207fd841f27c742b955a882.png

提出问题

为什么要用这个布局?

怎么用这个布局?

不足在哪里?

优势

ConstraintLayout就是为性能而生,目标就是减少布局嵌套,提高measure+layout性能,来看看官方给出的数据。

dd580888f46f4cf676684c19d5be8493.png

ConstraintLayout 在测量/布局阶段的性能比 RelativeLayout大约高40%!而它使用的性能检测工具是Android 7.0(API 级别 24)中引入的 OnFrameMetricsAvailableListener。通过该类,你可以收集有关应用界面渲染的逐帧时间信息,进而比较分析不同布局每次测量和布局操作所花费的时间。

另外使用AS的图形化界面可以非常方便的完成布局操作,这里不赘述了文末有参考文章。

配置

引入最新版本constraint layout库

implementation 'com.android.support.constraint:constraint-layout:1.1.3'

复制代码

旧界面转换为ConstraintLayout

首先,AS支持一键将已有的布局文件转成ConstraintLayout,是不是很贴心,要做就做全套的。

8ec78aa08cec334abe5c4a244f58ad81.png

用法

1. 属性layout_constraintXXX_toYYYOf

xxx表示该控件在哪个方向的约束,YYY表示该约束指向的控件的方向(我已经尝试说人话了...),它们的可以是 left/right/top/bottom/start/end的任意一种,包含了水平方向和垂直方向的约束,属性的值为目标控件的id,看个例子item1_constraint.xml。

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">

android:id="@+id/titleTextView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello World1!"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent" />

android:id="@+id/subtitleTextView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello World2!"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toBottomOf="@id/titleTextView" />

复制代码

a422626ee0dfa0aa2e31b8ff24b89935.png

可以看到两个控件水平方向的约束都指向parent也就是父控件ConstraintLayout,由于两边拉力作用就成了居中的样式,垂直方向上由于第二个textview使用了约束app:layout_constraintTop_toBottomOf="@id/titleTextView",即它的顶部约束为在第一个textview的下面,也就形成了效果图的样子。

2. match_constraint

由于ConstraintLayout的设计就是不想出现层次嵌套,这导致传统布局里使用的match_parent也就不适用了。那如何实现match_parent的效果呢?来看一个例子test_match_constraint.xml。

android:layout_width="match_parent"

android:layout_height="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto">

android:id="@+id/bt1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="button1" />

android:layout_width="0dp"

android:layout_height="wrap_content"

android:text="button1"

app:layout_constraintLeft_toRightOf="@id/bt1"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="@id/bt1"/>

复制代码

aa7066757fb52092b3c39ae23f3ae7ab.png

可以看到将第二个button的layout_width设置为0dp后,它并没有不显示出来而是占据的水平方向的剩余空间。没错,在ConstraintLayout中宽高指定为0dp表示的是在满足约束条件下的最大值,也即match_constraint。

3. 宽高比layout_constraintDimensionRatio

不多BB直接看示例test_dimension_ratio.xml

android:layout_width="match_parent"

android:layout_height="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto">

android:id="@+id/banner"

android:layout_width="300dp"

android:layout_height="0dp"

android:text="banner"

android:gravity="center"

android:textSize="30sp"

android:background="@android:color/holo_blue_light"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintDimensionRatio="2:1"/>

复制代码

2832289878552058fd22f29173e85a68.png

可以看到设置app:layout_constraintDimensionRatio="2:1属性表示宽高比为2:1,在已经限定控件宽度为300dp时,高度指定为0dp则可自己算出实际高度。

4. radius角度约束

秒懂的属性,直接来看例子test_radius.xml

android:layout_width="match_parent"

android:layout_height="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="按钮"

app:layout_constraintCircle="@id/fab_menu"

app:layout_constraintCircleRadius="100dp"

app:layout_constraintCircleAngle="45"/>

android:id="@+id/fab_menu"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:tint="#fff"

android:text="btn1"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent" />

复制代码

89783b6e82eb7f049ed0ccfa5027bcad.png

5. bias偏向拉力比例

示例test_bias.xml

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/button"

android:layout_width="50dp"

android:layout_height="wrap_content"

app:layout_constraintHorizontal_bias="0.8"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent" />

复制代码

2535a6f4ba60651eaec0e1855f5d0af9.png

可以看到虽然水平方向都有拉力,但设置了layout_constraintHorizontal_bias属性后产生了偏移,属性值从0到1,0为最左侧1为最右侧,需要注意的是该属性只有水平方向上都有约束才会生效。

6. 链chain

水平或垂直方向上相互约束的两个或更多view组成一个约束链,通常可用于实现底部导航样式,示例test_chain.xml

android:layout_width="match_parent"

android:layout_height="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto">

android:id="@+id/bt1"

android:layout_width="0dp"

android:layout_height="wrap_content"

app:layout_constraintHorizontal_weight="2"

android:text="第一个"

android:textSize="30sp"

app:layout_constraintHorizontal_chainStyle="spread_inside"

app:layout_constraintRight_toLeftOf="@id/bt2"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent" />

android:id="@+id/bt2"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:text="第二个"

android:textSize="30sp"

app:layout_constraintHorizontal_weight="1"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toRightOf="@id/bt1"

app:layout_constraintRight_toLeftOf="@id/bt3"/>

android:id="@+id/bt3"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="第三个"

android:textSize="30sp"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintLeft_toRightOf="@id/bt2" />

复制代码

效果图

8afa39cee4e12f55f1f0508049612b86.png

其中layout_constraintHorizontal_chainStyle属性可设置一个约束链中view的分布情况。4b94fcff639e0e60ac92223945cc103f.png

本例结合layout_constraintHorizontal_weight属性实现了weight chain效果。

7. GuideLine参照线

为方便的指定约束的参照对象,ConstraintLayout内部可通过GuideLine来实现,它不会显示在界面中。

示例test_guideline.xml

android:layout_width="match_parent"

android:layout_height="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto">

android:id="@+id/guideline"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="vertical"

app:layout_constraintGuide_begin="100dp"/>

android:id="@+id/btn1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="btn1"

android:textSize="30sp"

app:layout_constraintLeft_toRightOf="@+id/guideline"

app:layout_constraintTop_toTopOf="parent"/>

复制代码

8cdc91a27ee24e89ad9dff06996fc48f.png

可以看到通过layout_constraintGuide_begin指定具体偏移值,而通过layout_constraintGuide_percent可指定偏移百分比。

8. 属性goneMargin

当约束对象可见性设置为gone后生效,示例test_gone_margin.xml。

android:layout_width="match_parent"

android:layout_height="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto">

android:id="@+id/bnt1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="30sp"

app:layout_constraintLeft_toLeftOf="parent"

android:visibility="gone"

android:text="bnt1"/>

android:id="@+id/bnt2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="30sp"

app:layout_constraintLeft_toRightOf="@id/bnt1"

app:layout_goneMarginLeft="200dp"

android:visibility="visible"

android:text="bnt2"/>

复制代码

b7afb1341bae672659597597e1499166.png

9. 其他

layout_constrainedWidth

针对view宽高为wrap_content时,控件的实际宽高超过了约束条件时应该如何显示,默认是false,示例test_constraint_width.xml。

控件Barrier-- 限定范围,示例test_barrier.xml。

控件Group--引用的组件可批量设置属性,示例test_group.xml。

控件PlaceHolder--占位符,示例test_place_holder.xml。

其他综合练习参照test_common.xml、test_video_constraint.xml。

注意事项

没有约束的layout_marginTop等属性无效。

代码布局

实际开发过程中难免需要使用代码动态布局,整体思路为下面的代码,具体示例参照ProgramActivity.class。

//1.创建约束条件

ConstraintSet set = new ConstraintSet();

//2.从一个ConstraintLayout中克隆出所有的约束条件。

set.clone(layout)

//3.约束条件和constraintLayout绑定

set.applyTo(constraintLayout);

复制代码

缺点

xml文件没有布局层次,可读性差

代码布局复杂性高

约束条件复杂时排查难度大

性能对比

下面是最重要的一趴,ConstraintLayout真的如官方宣传的具备高性能吗?我们使用简单布局和复杂布局两种场景模拟实际开发情况,使用的单元测试为LayoutTest.class,得到如下结果。

cf2ccdd989d3d516f57bd77f84691078.png

简单布局表示布局中仅有一层嵌套,上图横坐标表示一次测量和布局的时间,单位为ms,纵轴表示直观上这个简单布局使用哪种传统布局更方便实现,比如我们要实现一个纵向的简单列表,显然线性布局更易实现。通过结果可以看到ConstraintLayout的性能比传统布局的性能差至少一倍。

ef800f08b77f95b51b3e0e9a0c99b553.png

如果说简单布局耗时本来就极少参考意义不大,那复杂布局呢?复杂布局情况下中使用传统布局会导致3-4层的嵌套,符合常见的开发场景,但性能方面仍优于ConstraintLayout,其中FrameLayout的性能表现最好。

结语

关于性能的评测国外的文章也很多,都有得出类似的结论,他们大都归咎于随着ConstrainLayout版本的升级,引入更多的功能而导致性能下降,但博主使用许多更低版本的库测试,结果差别也不大,这就是为什么文章要起这个标题。如果性能没跟上,那由于ConstrainLayout许多缺点的存在,我们完全没有理由选择使用它,期待官方会做进一步优化工作。当然博主后续也会使用其他工具(systrace等)进一步验证此结论。

后记勘误

以上评测使用的是模拟器,笔者也不解为何会出现明显与google大大结果不一致的情况。考虑到真机与模拟器的差异性,笔者使用真机再次验证发现结果与模拟器大相径庭。测试过的真机Android版本为4.4/5.0/6.0。

36c6ed6051d3d170cef002b244ab55f5.png

使用ConstraintLayout作为根布局比其他布局

性能至少提升25%!

至于原因笔者暂时还不清楚,欢迎大神指点迷津。同时对之前评测的结果与得出的结论如有误导已读读者表示十分抱歉。

另有一点遗漏:从1.1版本后官方还提供了一个实验性的优化参数。

app:layout_optimizationLevel

复制代码

官方文档附上,小伙伴可以尝试。

b72b773e731124d171a6240f782892f3.png

参考文章:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android五种布局局限性,android ConstraintLayout布局从入门到放弃 的相关文章

  • IDEA如何导入Eclipse项目-靠谱

    小伙伴在用到IDEA的时候 将已有的Eclipse项目导入到IDEA中 遇到各种问题 我总结了一下 仅供参考 我的工具版本是 IntelliJ IDEA 2017 1 5 1 open的项目目录展示 实际文件目录 打开的项目目录展示 2 点
  • Java High Level REST Client 中文API(仅供参考)

    1 初始化 兼容性 Java High Level REST Client需要Java 1 8 并依赖于Elasticsearch核心项目 客户端版本与客户端开发的Elasticsearch版本相同 它接受与TransportClient相
  • PyQt的动作(QAction)

    前言 Qt的设计师程序能够识别用户界面中用户做同样事情时所经常使用的不同种方法 例如 在许多应用中创建一个新文件可以使用File gt New菜单项 或者通过点击按钮图标 或者使用快捷键等 对于用户是如何执行动作的我们并不关心 关心他们到底
  • 第一章: Mysql体系结构和存储引擎

    文章目录 1 1 定义数据库和实例 1 2 Mysql体系结构 1 3 Mysql存储引擎 1 4 常见问题解答 1 5 存储引擎相关操作语法 1 6 连接Mysql 1 1 定义数据库和实例 数据库和实例的区别 数据库是物理操作系统或其他
  • 让别人写一个python爬虫程序大概要多少钱?

    前言 目前 对于程序代做来说没有统一标准 不像论文那样可以按照字数来定价 根据行业经验 总结出了一个python代写的参考价格 一般来说如果想写本科的python作业 一般是500起 硕士作业按照项目算的话 一般是1500起 影响pytho
  • JS的作用域问题

    一 块级作用域 在 JavaScript 中 作用域为可访问变量 对象 函数的集合 js没有块级作用域 你可以自己闭包或其他方法实现 只有函数级作用域 函数外面的变量函数里面可以找到 函数里面的变量外面找不到 var a 10 functi
  • Nginx 七层和四层负载均衡——筑梦之路

    七层负载均衡示例配置 worker processes 2 events worker connections 1024 7层http负载 http include mime types default type application o
  • Python全栈开发【基础-07】与用户交互

    专栏介绍 本专栏为Python全栈开发系列文章 技术包括Python基础 函数 文件 面向对象 网络编程 并发编程 MySQL数据库 HTML JavaScript CSS JQuery bootstrap WSGI Django Flas
  • C++ list, vector, map, set 区别与用法比较

    一 list和vector List封装了链表 Vector封装了数组 list和vector得最主要的区别在于vector使用连续内存存储的 他支持 运算符 而list是以链表形式实现的 不支持 Vector对于随机访问的速度很快 但是对
  • 华为OD机试真题 Java 实现【组合出合法最小数】【2023Q1 200分】,附详细解题思路

    一 题目描述 给一个数组 数组里面都是代表非负整数的字符串 将数组里所有的数值排列组合拼接起来组成一个数字 输出拼接成的最小的数字 二 输入描述 一个数组 数组不为空 数组里面都是代表非负整数的字符串 可以是0开头 例如 13 045 09
  • Tkinter模拟发送邮箱验证码并在指定时间后验证码过期

    先上两张图 再解释 运行原理 程序运行后 输入要接收验证码的邮箱地址 点击 发送 后 控制台打印输出得到的验证码并发送到邮箱里 过了15秒以后 验证码再次刷新 并打印输出 这样就实现了动态过期 原理就是到某个时间点我再刷新一遍生成验证码函数
  • Hadoop命令大全

    目录 基本语法 一 上传 二 下载 三 其他增删改查操作 3 1 增 3 2 删 3 3 改 3 4 查 基本语法 hadoop fs 和 hdfs dfs hadoop fs和hdfs dfs命令等效 hdfs dfs 只能操作HDFS文
  • FISCO-BCOS学习——区块链浏览器搭建

    注意 本系列文章遇到的问题都可以参考查找 官方文档 或 本系列问题总结 FISCO BCOS 及 WeBase 问题记录 FISCO BCOS 官方文档 WeBase 官方文档 FISCO BCOS区块链浏览器搭建 前提条件 环境 版本 J
  • STM32的HAL库SPI操作(master 模式)-根据时序图配置SPI

    SPI相关基础知识 SPI基本概念请自行百度 参考 百度百科SPI简介 我们讲重点和要注意的地方 master模式下要关注的地方 接线一一对应 也就是说主控的MISO MOSI SCLK CSn 分别和设备的MISO MOSI SCLK C
  • 数据清洗之朝阳医院2018年销售数据分析

    朝阳医院2018年销售数据分析 所用到的数据提取地址 gt 戳这里下载 或私我 过程 整体代码 导入库 import pandas as pd import numpy as np import matplotlib pyplot as p
  • STM32F103ZET6---【硬件篇】定时器

    STM32的TIM1 TIM8为高级定时器 TIM2 TIM3 TIM4 TIM5为通用定时器 TIM6 TIM7为基本定时器 各个定时器引脚如下 TIM1和TIM8定时器的功能包括 16位向上 向下 向上 下自动装载计数器 16位可编程
  • RealBasicVSR训练(三)用自己的数据集训练

    由于上一篇中的方法只能用1个gpu训练 故重新采取之前的训练方法 第一步 RealBasicVSR master mim train mmedit configs realbasicvsr wogan c64b20 2x30x8 lr1e
  • 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java基于HTML5的流浪动物领养平台yww0b

    很多大学生 成考 自考 全日制本科 大专的学生都因为毕设没有完成而延时毕业的情况 现在分享给大家选题 下面有2023年做的选题 最后面有选题 源码 论文下载网站给大家学习 如今计算机技术的飞速发展 大约三 四年前 软件工程是市场的热门领域
  • 电荷泵电路(Charge Pump)用于升压的解析

    升压的电荷泵电路 Charge Pump 也称为开关电容转换器 Switched Capacitor Converter 老粉丝都知道 公众号很久之前就发布了一篇阐述电感 电容 二极管构成的BOOST升压方案的文章 那为什么还要讨论电荷泵方

随机推荐

  • 小谈类机制相关

    小谈类机制相关 本文主要涉及类相关的一些常见面试问题 以及相关特性 包括 this 指针 拷贝构造函数相关以及类机制 一 this指针 编译器在编译普通成员函数时 会隐式的分配一个形参指针 即this指针 并且当实例化对象调用该成员函数时
  • Python 时间比较大小 并从dataframe中提取满足时间条件的量

    之前一直用时间数据相互加减然后判断是否大于0来判断大小 但是发现时间数据居然可以直接比较 Python 时间比较大小 可以直接用比较运算符 gt lt 输出bool类型 True False 先定义一个包含时间数据的dataframe t1
  • python None理解与应用

    官方文档 None是NoneType类型的唯一值 所以None既不是空列表 也不是空字符串 None通常用来代表空值 或者表示函数默认没有入参 如下图 None不能被赋值 否则会报错 它跟True False一样也是built in con
  • android Intent 全面点的介绍

    第一种方式 用action来跳转 1 使用Action跳转 如果有一个程序的AndroidManifest xml中的某一个Activity的IntentFilter段中 定义了包含了相同的Action那么这个Intent就与这个目标Act
  • Linux线程

    目录 1 进程线程区别 2 线程 创建退出等待 3 互斥量 锁 3 什么是死锁 4 条件 5 线程初始化宏 6 生产者消费者 1 进程线程区别 1 进程占内存 比如父子进程copy内存空间 线程共享内存空间 2 线程切换和创建速度比进程快
  • 主板24pin接口详图_工控电脑一般需要几个供电接口

    工控电脑也叫做工控机 是使用在工业上的计算机 由机箱 主板 CPU 内存 硬盘和电源等硬件设备所组成 既然工控电脑是计算机的一种 那它工作的时候肯定是需要供电才能启动 那么工控电脑一般需要几个供电接口 一定要说工控电脑一般需要几个供电接口
  • 雷军的开源情怀

    2007 年 iPhone 发布 智能手机时代真正拉开帷幕 2009 年 Google 发布了开源的手机操作系统 Android 同年 9 月 第一款 Android 手机 G1 发布 尽管当时 Android 手机体验还很粗糙 但我认为
  • (MySql) InnoDB索引的本质和快速查询过程

    本文涉及的范围包括 1 到底什么是InnoDB引擎的索引 它的本质是什么 是如何实现的 实现的思路是什么 2 根据索引的实现思路 当我们要查询一条数据 行记录 时 查询语句的查询过程是什么 说到数据库引擎的索引 我们都知道它的作用是提高数据
  • MATLAB 中的randn函数

    matlab函数 randn 产生正态分布的随机数或矩阵的函数 randn 产生均值为0 方差 2 1 标准差 1的正态分布的随机数或矩阵的函数 用法 Y randn n 返回一个n n的随机项的矩阵 如果n不是个数量 将返回错误信息 Y
  • ESP8266和腾讯云的使用

    1 ESP8266简介 在乐鑫官网 ESP芯片技术厂家 可以看到 乐鑫把ESP8266称之为面向物联网应用的高性价比 高度集成的 Wi Fi MCU 简单来说 ESP8266可以有两种功能 一是WiFi模块 二是32位MCU WiFi模块
  • 向量与矩阵的相乘

    在学习计算机图形学的时候 最常遇到的就是矩阵的乘法了 下面我们就简单的介绍下 使用程序如何编写两个矩阵的相乘呢 其实这个问题 大一的孩子都会写的 不是很难的 但是呢 为了构建一个完整的学习过程 还是记录一下基础知识 1 向量乘以矩阵 如上图
  • 全栈开发学习(Node+Vue+Mongodb)(八)——移动端页面搭建(主页部分)

    前面我们完成了后台管理界面的基本功能 接下来就需要完成移动端页面的搭建与数据的展示 移动端的搭建主要以旧版王者荣耀官网主页样式为模板 本文主要介绍前端搭建的流程与一些基本组件的使用 1 准备工作 样式 思路 使用SASS规范化我们的所有样式
  • Obsidian同步方案(win+android)

    官方 Obsidian Git Mgit Onedirve Onedrive SyncTrayzor Syncthing Obsidian Git Mgit 步骤 下载 按照俩个教程配置 有问题私聊 几天内回复 注意点 ObsidianGi
  • RLE压缩算法详解

    RLE压缩算法详解 RLE Run Length Encoding 行程长度压缩算法 也称游程长度压缩算法 是最早出现 也是最简单的无损数据压缩算法 RLE算法的基本思路是把数据按照线性序列分成两种情况 一种是连续的重复数据块 另一种是连续
  • 数据挖掘个人理解

    lt 1 gt 数据挖掘 1 通过对大量数据进行分析 从大量数据中发现一些客观规律 结论 2 主要有数据准备 规律寻找 规律表示3大步 3 步骤 采集数据 采集相关技术 整合检查数据 去除错误数据 建立合适模型进行数据分析 进行数据挖掘工作
  • Markdown基础语法详细版

    文章目录 1 Markdown简介 2 Markdown特点 3 Markdown基本语法 3 1 标题 3 2 斜体和粗体 3 3 换行 3 4 分割线 3 5 列表 3 5 1 无序列表 3 5 2 有序列表 3 5 3 定义型列表 3
  • Linux应用编程(文件IO进阶)

    一 Linux 系统如何管理文件 1 1 静态文件与 inode 文件存放在磁盘文件系统中 并且以一种固定的形式进行存放 我们把他们称为静态文件 每一个文件都必须对应一个 inode inode 实质上是一个结构体 这个结构体中有很多的元素
  • 手写个简单的promisify方法

    node中为了能方便使用async await语法 通常会使用promisify方法将node中遵循错误优先的api接口转换 返回一个Promise实例 从而无缝衔接使用async await语法 例如 async function var
  • CGAL点云处理之体素下采样

    体素下采样 点云体素采样 通过指定大小的网格 每个网格保留一个点云数据 void gridSimplifyPointsByCgal Point set points double threshold int size double spac
  • android五种布局局限性,android ConstraintLayout布局从入门到放弃

    布局优化是性能优化的一个方向点 包括了根据需求应该选用哪种布局容器 ViewStub懒加载 如何减少布局层级等 今天我们要探讨的就是如何使用ConstraintLayout来优化我们的布局层级 提出问题 为什么要用这个布局 怎么用这个布局