Android 四大布局:使用方式与性能优化原理

一、四大布局基本用法与特点

1. LinearLayout(线性布局)

使用方式

<LinearLayoutandroid:orientation="vertical"  <!-- 排列方向:vertical/horizontal -->android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="按钮1"/><Buttonandroid:layout_width="0dp"         <!-- 权重布局 -->android:layout_height="wrap_content"android:layout_weight="1"          <!-- 占剩余空间1/3 -->android:text="按钮2"/>
</LinearLayout>

特点

  • 单向排列(水平/垂直)

  • 权重分配(layout_weight

  • 痛点:实现复杂布局需多层嵌套 → 性能下降


2. FrameLayout(帧布局)

使用方式

<FrameLayoutandroid:layout_width="match_parent"android:layout_height="300dp"><ImageView.../>  <!-- 底层图片 --><Buttonandroid:layout_gravity="center" <!-- 居中定位 -->android:text="居中按钮"/><TextViewandroid:layout_gravity="bottom|end" <!-- 右下角定位 -->android:text="右下角文字"/>
</FrameLayout>

特点

  • 子视图堆叠在左上角

  • 通过 layout_gravity 调整位置

  • 痛点:无法实现复杂相对定位


3. RelativeLayout(相对布局)

使用方式

<RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/btn1"android:layout_alignParentTop="true" <!-- 贴父容器顶部 -->android:text="按钮1"/><Buttonandroid:layout_toRightOf="@id/btn1"  <!-- 在btn1右侧 -->android:layout_alignBottom="@id/btn1" <!-- 底部对齐btn1 -->android:text="按钮2"/>
</RelativeLayout>

特点

  • 基于兄弟/父容器相对定位

  • 痛点

    • 循环依赖导致测量失败(如A在B右侧,B在A左侧)

    • 需两次测量遍历(横向+纵向)→ 性能中等


4. ConstraintLayout(约束布局)

使用方式

<androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><!-- 基础约束 --><Buttonandroid:id="@+id/btn1"app:layout_constraintStart_toStartOf="parent" <!-- 贴父容器左侧 -->app:layout_constraintTop_toTopOf="parent"     <!-- 贴父容器顶部 -->android:text="按钮1"/><!-- 相对约束 + 边距 --><Buttonapp:layout_constraintStart_toEndOf="@id/btn1" <!-- 在btn1右侧 -->app:layout_constraintTop_toTopOf="@id/btn1"    <!-- 顶部对齐btn1 -->android:layout_marginStart="10dp"             <!-- 左边距10dp -->android:text="按钮2"/><!-- 水平链条均分 --><Buttonapp:layout_constraintHorizontal_chainStyle="spread"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toStartOf="@+id/btn3"/>
</androidx.constraintlayout.widget.ConstraintLayout>

特点

  • 通过锚点(约束)连接父容器/兄弟视图/辅助线

  • 高级功能:

    • 链条(Chains):替代线性布局权重

    • 比例约束(layout_constraintDimensionRatio

    • 虚拟辅助(Guideline/Barrier)


二、性能优化原理:测量过程流程图

1. LinearLayout 测量过程(嵌套时性能最差)

性能问题

  • 测量次数 = O(2ⁿ)(n为嵌套层数)

  • 每层嵌套需2次测量(父测量子 + 子自身测量)

  • 示例:3层嵌套 → 7次测量


2. RelativeLayout 测量过程

性能问题

  • 需 两次遍历(横向+纵向)

  • 循环依赖导致 重复测量

  • 测量次数 = O(n²)(n为子视图数量)


3. ConstraintLayout 测量过程

性能优势

  • 单次测量完成(O(n) 复杂度)

  • 约束求解器(Constraint Solver)将布局问题转化为 数学方程组求解


三、为什么ConstraintLayout性能最优?

1. 减少嵌套 → 减少测量次数
布局实现相同界面所需层级测量复杂度
LinearLayout5层O(2⁵)=32
RelativeLayout3层O(n²)=9
ConstraintLayout1层O(n)=3
2. 测量机制本质差异
  • 传统布局:递归测量 → 父布局等待子布局测量结果 → 同步阻塞式

  • ConstraintLayout

    1. 收集所有约束条件

    2. 约束求解器 一次性计算 所有视图位置

    3. 应用计算结果 → 异步批处理式

3. 硬件加速优化
  • 约束条件转化为GPU可执行的 图形指令

  • 减少CPU计算量(尤其旋转屏幕等布局重构场景)


四、常见问题

Q:为什么ConstraintLayout能减少性能开销?

A

  1. 扁平化布局设计

    • 通过约束关系直接定位视图,避免多层嵌套(如用链条替代LinearLayout权重)

    • 减少视图树深度,直接降低测量/绘制复杂度

  2. 单次测量机制

    • 传统布局(如LinearLayout)嵌套时测量次数呈 指数级增长(O(2ⁿ))

    • ConstraintLayout使用 约束求解器 一次性计算所有视图位置,测量次数 优化为O(n)

  3. 硬件加速支持

    • 约束条件转化为GPU指令(减少CPU负担)

    • 官方测试:渲染速度比RelativeLayout快40%

结论
对于复杂界面,ConstraintLayout通过减少嵌套+单次测量,从根本上解决Android布局性能瓶颈。


五、各布局适用场景总结

布局最佳使用场景性能风险点
LinearLayout简单列表/表单嵌套超过3层时性能骤降
FrameLayout碎片容器/悬浮按钮多子视图定位困难
RelativeLayout中等复杂度相对定位子视图超过10个时测量缓慢
ConstraintLayout所有复杂界面超简单布局略显繁琐

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis的BigKey问题

Redis的BigKey问题 什么是大Key问题&#xff1f; 大key问题其实可以说是大value问题&#xff0c;就是某个key对应的value所占据的存储空间太大了&#xff0c;所以导致我们在操作这个key的时候花费的时间过长&#xff08;序列化\反序列化&#xff09;&#xff0c;从而降低了redi…

TDengine IDMP 产品基本概念

基本概念 元素 (Element) IDMP 通过树状层次结构来组织数据&#xff0c;树状结构里的每个节点被称之为元素 (Element)。元素是一个物理的或逻辑的实体。它可以是具体的物理设备&#xff08;比如一台汽车&#xff09;&#xff0c;物理设备的一个子系统&#xff08;比如一台汽车的…

专题二_滑动窗口_将x减到0的最小操作数

一&#xff1a;题目解释&#xff1a;每次只能移除数组的边界&#xff0c;移除的边界的总和为x&#xff0c;要求返回你移除边界的最小操作数&#xff01;也就是说你最少花几次移除边界&#xff0c;就能够让这些移除的边界的和为x&#xff0c;则返回这个次数&#xff01;所以这个…

CentOS 7 下通过 Anaconda3 运行llm大模型、deepseek大模型的完整指南

CentOS 7 下通过 Anaconda3 运行llm大模型、deepseek大模型的完整指南A1 CentOS 7 下通过 Anaconda3 运行大模型的完整指南一、环境准备二、创建专用环境三、模型部署与运行四、优化配置常见问题解决B1 CentOS 7 下通过 Anaconda3 使用 CPU 运行 DeepSeek 大模型的完整方案一、…

Flutter应用在Windows 8上正常运行

要让Flutter应用在Windows 8上正常运行,需满足以下前提条件,涵盖系统环境、依赖配置、编译设置等关键环节: 一、系统环境基础要求 Windows 8版本 必须是 Windows 8.1(核心支持),不支持早期Windows 8(需升级到8.1,微软已停止对原版Windows 8的支持)。 确认系统版本:右…

Redis实现消息队列三种方式

参考 Redis队列详解&#xff08;springboot实战&#xff09;_redis 队列-CSDN博客 前言 MQ消息队列有很多种&#xff0c;比如RabbitMQ,RocketMQ,Kafka等&#xff0c;但是也可以基于redis来实现&#xff0c;可以降低系统的维护成本和实现复杂度&#xff0c;本篇介绍redis中实现…

【C++动态版本号生成方案:实现类似C# 1.0.* 的自动构建号】

C动态版本号生成方案&#xff1a;实现类似C# 1.0.* 的自动构建号 在C#中&#xff0c;1.0.*版本号格式会在编译时自动生成构建号和修订号。本文将介绍如何在C项目中实现类似功能&#xff0c;通过MSBuild自动化生成基于编译时间的版本号。 实现原理 版本号构成&#xff1a;主版本…

【算法题】:斐波那契数列

用 JavaScript 实现一个 fibonacci 函数&#xff0c;满足&#xff1a; 输入 n&#xff08;从0开始计数&#xff09;输出第 n 个斐波那契数&#xff08;斐波那契数列从 1 开始&#xff1a;1,1,2,3,5,8,13,21…&#xff09; 示例&#xff1a; fibonacci(0) > 1fibonacci(4) &g…

【YOLOv13[基础]】热力图可视化实践 | 脚本升级 | 优化可视化效果 | 论文必备 | GradCAMPlusPlus, GradCAM, XGradCAM, EigenCAM等

本文将进行添加YOLOv13版本的升级版热力图可视化功能的实践,支持图像热力图可视化、优化可视化效果、 可以选择使用GradCAMPlusPlus, GradCAM, XGradCAM, EigenCAM, HiResCAM, LayerCAM, RandomCAM, EigenGradCAM。一个参数即可设置是否显示检测框等。 原图 结果图

ElasticSearch相关术语介绍

1.RESTful风格程序REST(英文全称为:"Representational State Transfer")指的是一组架构约束条件和原则。它是一种软件架构风格&#xff08;约束条件和原则的集合&#xff0c;但并不是标准&#xff09;。 REST通过资源的角度观察网络&#xff0c;以URI对网络资源进行…

《从零构建大语言模型》学习笔记4,注意力机制1

《从零构建大语言模型》学习笔记4&#xff0c;自注意力机制1 文章目录《从零构建大语言模型》学习笔记4&#xff0c;自注意力机制1前言一、实现一个简单的无训练权重的自注意力机制二、实现具有可训练权重的自注意力机制1. 分步计算注意力权重2.实现自注意力Python类三、将单头…

昇思+昇腾开发板+DeepSeek模型推理和性能优化

昇思昇腾开发板DeepSeek模型推理和性能优化 模型推理 流程&#xff1a; 权重加载 -> 启动推理 -> 效果比较与调优 -> 性能测试 -> 性能优化 权重加载 如微调章节介绍&#xff0c;最终的模型包含两部分&#xff1a;base model 和 LoRA adapter&#xff0c;其中base …

未给任务“Fody.WeavingTask”的必需参数“IntermediateDir”赋值。 WpfTreeView

c#专栏记录&#xff1a; 报错 未给任务“Fody.WeavingTask”的必需参数“IntermediateDir”赋值。 WpfTreeView 生成 解决办法 清理和重新生成项目 完成上述配置后&#xff0c;尝试执行以下步骤&#xff1a; 清理项目&#xff1a;删除 bin 和 obj 文件夹。 重新生成项目&…

[Linux]学习笔记系列 -- [arm][lib]

文章目录arch/arm/lib/delay.cregister_current_timer_delay 注册当前定时器延迟read_current_timer 读取当前定时器drivers/clocksource/timer-stm32.cstm32_clocksource_init STM32 平台上初始化时钟源https://github.com/wdfk-prog/linux-study arch/arm/lib/delay.c regis…

harbor仓库搭建(配置https)

目录 1. 环境准备 2. 配置https的原因 3. 生成ca证书 4. 搭建harbor仓库 5. 访问harbor 6. 修改加密算法 1. 环境准备 需要提前安装docker和docker-compose&#xff0c;harbor仓库版本越新&#xff0c;对应的docker和docker-compose版本越新。 主机IP192.168.48.19dock…

C++多线程服务器

C多线程服务器 因为自己同时在看多本书&#xff0c;之前看过《TCP/IP 网络编程》一书&#xff0c;其中有一个自己编写一个多线程服务器的例子&#xff0c;于是就把代码直接抄了一变。 在学习网络编程前需要先了解网络的7层模型。 具体代码如下&#xff1a; 服务器端&#xff1a…

【Pandas】常用数据处理技巧

一. 数据读取 1.pd.to_csv & pd.read_csv 细节&#xff1a; 1.pd.read_csv 需要 ignore_index True or ,index_col0 否则会有列Unnamed0 2.pickle具有更快的读取速度&#xff0c;与更小的体积。 读取前N行&#xff08;若不需获取所有数据&#xff09; pd.read_csv(…

Docker Compose 部署高可用 MongoDB 副本集集群(含 Keepalived + HAProxy 负载均衡)

Docker Compose 部署高可用 MongoDB 副本集集群&#xff08;含 Keepalived HAProxy 负载均衡&#xff09;背景与目标&#x1f4cb; 环境规划**服务器信息****软件版本**部署步骤1. 创建目录结构2、生成 keyFile&#xff08;三台机器内容必须一致&#xff09;3. 准备 Keepalive…

MySQL(189)如何分析MySQL的锁等待问题?

分析MySQL的锁等待问题有助于发现和解决数据库性能瓶颈。锁等待问题通常会导致数据库响应时间变长&#xff0c;影响系统的整体性能。以下是详细深入的方法和代码示例&#xff0c;帮助你分析和解决MySQL的锁等待问题。 一、锁的类型和概念 在MySQL中&#xff0c;主要有以下几种锁…

26.Scikit-learn实战:机器学习的工具箱

Scikit-learn实战&#xff1a;机器学习的工具箱 &#x1f3af; 前言&#xff1a;机器学习界的"宜家家具" 还记得第一次逛宜家的感受吗&#xff1f;琳琅满目的家具&#xff0c;每一件都有详细的说明书&#xff0c;组装简单&#xff0c;样式统一&#xff0c;关键是—…