Android 详解布局优化之include与merge

我的Android App启动又快了0.5秒:聊聊<ViewStub>和<include>在复杂页面中的‘懒加载’艺术 本文深入探讨了Android性能优化中ViewStub和Include的懒加载艺术,通过电商App首页的实战案例,展示了如何减少冷启动时间、降低内存占用。重点解析了ViewStub的延迟加载机制和Include的模块化设计,帮助开发者提升复杂页面的渲染效率,实现0.5秒的启动优化突破。 阅读详情


Android 官方提供了三个用来优化布局的标签,分别是include、merge与ViewStub,其中ViewStub是动态加载视图到内存,大家可以查阅:Android UI布局优化之ViewStub

一、include布局重用:

在Android的应用程序开发中,标题栏是必不可少的一个元素,大部分页面都要用到,而且布局都是一样的,这时候使用include标签就显得极其的方便。使用时通常需要注意以下几点。

  1. include标签的layout_*属性会替换掉被include视图的根节点的对应属性。
  2. include标签的id属性会替换掉被include视图的根节点id
  3. 一个布局文件中支持include多个视图,但是这样会导致获取被include视图内的控件时, 
    解决方法请参考:www.coboltforge.com/2012/05/tech-stuff-layout/

下面例子中,titlebar_layout.xml为标题栏布局,而activity_main.xml为主界面布局,activity_setting.xml为设置页面布局,这这两个界面中都include了titlebar_layout.xml视图。 
titlebar_layout.xml: 
titlebar_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/preference_activity_title_root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="2dip"
    android:background="@drawable/zns_activity_title_bg">

    <TextView
        android:id="@+id/preference_activity_title_text"
        android:layout_width="match_parent"
        android:layout_height="45dip"
        android:gravity="center"
        android:text="123"
        android:textColor="#ffffff"
        android:textSize="18sp" />

    <ImageView
        android:id="@+id/preference_activity_title_image"
        android:layout_width="30dip"
        android:layout_height="25dip"
        android:layout_gravity="center_vertical"
        android:scaleType="fitCenter"
        android:layout_marginLeft="5dip"
        android:src="@drawable/common_menu_selector_white" />
</FrameLayout>

主界面: 
主界面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#000000">

    <include layout="@layout/titlebar_layout"></include>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="这是内容区域"
        android:gravity="center"
        android:textSize="25sp"
        android:textColor="#ffffff"/>
</LinearLayout>

当然,其他界面使用include同样能包含该标题栏。

一、通过merge减少视图节点:

merge翻译成中文是合并的意思,在Android中通过使用merge能够减少视图的节点数, 
从而减少视图在绘制过程消耗的时间,达到提高UI性能的效果。使用merge时通常需要注意以下几点:

  1. merge必须放在布局文件的根节点上。
  2. merge并不是一个ViewGroup,也不是一个View,它相当于声明了一些视图,等待被添加。
  3. merge标签被添加到A容器下,那么merge下的所有视图将被添加到A容器下。
  4. 因为merge标签并不是View,所以在通过LayoutInflate.inflate方法渲染的时候, 第二个参数必须指定一个父容器,且第三个参数必须为true,也就是必须为merge下的视图指定一个父亲节点。
  5. 如果Activity的布局文件根节点是FrameLayout,可以替换为merge标签,这样,执行setContentView之后,会减少一层FrameLayout节点。
  6. 自定义View如果继承LinearLayout,建议让自定义View的布局文件根节点设置成merge,这样能少一层结点。
  7. 因为merge不是View,所以对merge标签设置的所有属性都是无效的。

其中第一点,我们看看LayoutInflate类的源码说明:

} else if (TAG_MERGE.equals(name)) {
    // 如果merge不是根节点,报错
    throw new InflateException("<merge /> must be the root element");
}

其中第三点,常用在自定义View中遇到,附上系统LayoutInflate类,对于该现象的源码:

if (TAG_MERGE.equals(name)) {
    // 如果是merge标签,指定的root为空,或则attachToRoot为false,则抛出异常信息
    if (root == null || !attachToRoot) {
        throw new InflateException("<merge /> can be used only with a valid "
                + "ViewGroup root and attachToRoot=true");
    }

    rInflate(parser, root, attrs, false, false);
}

针对第五点,做一下对比: 
布局文件1:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:text="顶部Button" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:text="底部Button" />

</merge>

效果1: 
效果一

布局文件2:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:text="顶部Button" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:text="底部Button" />

</FrameLayout>

效果2: 
效果二

我们可以看到,如果使用merge,明显少了一个FrameLayout节点,这也算一个视图优化技巧。

下面对第六条(自定义View如果继承LinearLayout,建议让自定义View的布局文件根节点设置成merge,这样能少一层结点)进行分析: 
先看看效果,就是一个线性布局,上下各一个TextView,看看使用merge和不使用merge的视图节点, 
以及使用merge的时候layoutInflate类的注意点。 
效果图: 
效果图 
第一种情况(不使用merge): 
布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.0"
        android:background="#000000"
        android:gravity="center"
        android:text="第一个TextView"
        android:textColor="#ffffff" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.0"
        android:background="#ffffff"
        android:gravity="center"
        android:text="第一个TextView"
        android:textColor="#000000" />

</LinearLayout>

代码:

/**
 * 自定义的View,竖直方向的LinearLayout
 */
public class MergeLayout extends LinearLayout {

    public MergeLayout(Context context) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.merge_activity, this, true);
    }
}

视图树: 
视图树一

我们发现,MergeLayout这个自定义控件的下面并不是直接跟着两个TextView, 
而是多了一个LinearLayout。

第二种情况(使用merge): 
注意因为为merge标签的设置的属性都不会生效,所以原来LinearLayout标签上的属性需要转移到java代码中设置。 
布局文件:

<?xml version="1.0" encoding="utf-8"?>
<!-- 习惯性的标记一下,MergeLayout布局 android:orientation="vertical" -->
<merge xmlns:android="http://schemas.android.com/apk/res/android" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.0"
        android:background="#000000"
        android:gravity="center"
        android:text="第一个TextView"
        android:textColor="#ffffff" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.0"
        android:background="#ffffff"
        android:gravity="center"
        android:text="第一个TextView"
        android:textColor="#000000" />

</merge>

个人习惯在用merge的时候在旁边标明使用到的属性,以防忘记。

java代码中需要设置orientation属性:

/**
 * 自定义的View,竖直方向的LinearLayout
 */
public class MergeLayout extends LinearLayout {

    public MergeLayout(Context context) {
        super(context);
        // 设置为数值方向的布局
        setOrientation(VERTICAL);
        LayoutInflater.from(context).inflate(R.layout.merge_activity, this, true);
    }
}

再看看视图树: 
视图树二 
我们发现,LinearLayout节点被去掉了。但是最终显示给用户的界面却是一样的。

总结

1. 使用include标签可以增加布局的复用性,提高效率。
2. 使用merge标签可以减少视图树中的节点个数,加快视图的绘制,提高UI性能。
3. merge标签的使用,看上去一次只减少一个节点,但是当一个布局嵌套很复杂的时候,
节点的个数可能达到几百个,这个时候,如果每个地方都多一个节点,视图的绘制时间相应的也就变长了很多。

UI性能的优化还有另外一个比较重要的知识点ViewStub,它是一个View,但是它几乎不占用资源, 

使用ViewStub能够加快视图的绘制,提高性能。

尊重原创,转载请注明出处:http://blog.youkuaiyun.com/a740169405/article/details/50473909

Android布局优化:include 、merge、ViewStub的详细总结 一、include的用法以及注意点 在开发Android布局时,我们常将一些通用的视图提取到一个单独的layout文件中,然后使用<include>标签在需要使用的其他layout布局文件中加载进来,比如我们自己App导航栏等。这样,便于对相同视图内容进行统一的控制管理,提高布局重用性。 下面我们以大部分项目中都有的头部导航栏为例,说明一下include的使用,比如我们项目自己统一... 阅读详情

相关推荐

Android include与merge标签的使用详解

当我们使用include标签将一个布局文件包含到另一个布局文件时,被包含布局的根节点会成为主布局文件的子节点。但有些情况下,我们并不需要包含布局的根节点,而只是想要将包含布局中的视图和布局结构直接插入到主布局中。在Android开发中,我们经常会遇到需要在多个布局文件中重复使用相同的视图或布局结构的情况。在主布局的XML文件中引入include标签后,被包含布局的所有视图和布局结构都会被插入到主布局中。include标签可以将一个布局文件(被包含布局)插入到另一个布局文件(主布局)中,实现布局的重用。

WELL_CODER的博客 579

Android merge

Android merge介绍

YK 2812

Android Include的使用:优雅地管理布局和控件(MVVM)

在Android开发中,布局文件往往会变得复杂而庞大,而控件的管理也变得棘手。为了更好地组织和重用布局代码,Android提供了标签,它允许我们将一个布局文件包含到另一个布局文件中。本文将详细介绍如何使用标签来优雅地管理布局和控件,并结合MVVM架构的实例。

FwgForth的博客 560

Android布局总结四:Merge总结

可以看到,这里我们将ok_cancel_layout最外层的LinearLayout布局删除掉,换用了merge标签,这就表示当有任何一个地方去include这个布局时,会将merge标签内包含的内容直接填充到include的位置,不会再添加任何额外的布局结构。接下来的部分就有问题了,在最外层的LinearLayout当中包含了两个元素,一个是EditText,另一个又是一个LinearLayout,然后在这个内部的LinearLayout当中才包含了确定和取消这两个按钮。看上去效果非常不错对吗?

chuyouyinghe的专栏 1904

Android中include和merge标签的使用

Android中include和merge标签的基本使用方法

HMC7044芯片模拟SPI配置

摘要: HMC7044是一款高性能双环路整数N分频抖动衰减器,支持SPI接口配置,适用于高速数据转换器时钟系统。该芯片采用双PLL级联架构,具有14路可配置输出,可满足GSM/LTE基站设计需求。SPI接口采用3线模式(SLEN/SCLK/SDATA),支持24位寄存器读写(13位地址+8位数据)。驱动实现基于Zynq EMIO模拟SPI,提供初始化、数据传输及寄存器配置功能,支持三线制工作模式和多种时钟参数设置。

toonyhe的博客 1094

Android布局优化:include 、merge、ViewStub标签详解

前言 在日常开发中,一个项目里可能会有很多相似的布局,如果我们每一个XML文件都写一次,不说麻烦,代码也显得冗余,而且可读性也很差。这时候我们可以将相同的布局提取出来重复使用。 Tips 使用Android Studio可以直接在布局文件对应控件:右键 -> Refactor -> Extract -> Style 抽取样式右键 -> Refactor -&g...

weixin_42046829的博客 850

别再被无限debugger卡住了!Chrome DevTools实战绕过技巧(含Hook与文件替换)

本文详细介绍了如何通过Chrome DevTools绕过无限debugger封锁的实战技巧,包括Hook技术与文件替换方法。针对常见的定时器轰炸、循环陷阱和动态注入等反调试手段,提供了高效的解决方案,帮助开发者快速突破调试障碍,提升爬虫和逆向工程效率。

weixin_30326515的博客 241

Android布局优化 include与merge标签使用详解

Android include与merge标签使用详解 1. 简介 include和merge标签的作用是实现布局文件的重用。就是说,为了高效复用及整合布局,使布局轻便化,我们可以使用include和merge标签将一个布局嵌入到另一个布局中,或者说将多个布局中的相同元素抽取出来,独立管理,再复用到各个布局中,便于统一的调整。 比如,一个应用中的多个页面都要用到统一样式的标题栏或底部导航栏,这时就...

Swust_ZzK的博客 857

SigFit实战:从FEA到光学仿真的热力耦合分析全流程解析

在光机系统与芯片封装等精密工程领域,热与力的耦合效应是影响产品性能与可靠性的核心物理问题。有限元分析(FEA)是预测结构在热、力载荷下变形与应力的基础工具,但其结果通常无法直接用于评估光学性能。这需要一座桥梁,将物理场数据转化为光学设计语言。其核心原理在于数据映射与面形表征技术,例如通过泽尼克多项式拟合,将离散的节点位移分解为离焦、像散等标准光学像差。这项技术的工程价值在于,它实现了多物理场仿真的闭环,使工程师能在设计阶段精准预测热变形或应力对波前误差、调制传递函数等关键光学指标的影响。其典型应用场景包括高

weixin_28630185的博客 337

美团外卖 mtgsig 1.2 逆向工程与补环境实战指南

本文深入解析了美团外卖核心风控参数mtgsig 1.2的生成机制与逆向实战。通过拆解其复杂的JSON结构,揭示了设备指纹、环境信息加密等关键字段。重点阐述了在Node.js中模拟浏览器环境(补环境)的核心方法,包括DOM/BOM对象、本地存储及Canvas/WebGL等高级指纹的模拟技巧,为安全研究和合规自动化测试提供了一套完整的技术指南。

uber9的博客 409

Android开发布局优化之ViewStub,include,merge标签详解

这里引入一位大神的博客

yaoyaoyao_123的博客 218

Coze离线部署实战:从镜像拉取到服务启动的完整避坑指南

本文提供了一份详尽的Coze平台离线部署实战指南。针对无外网的生产环境,详细讲解了从Docker镜像拉取、打包传输到内网服务器加载的完整流程,并重点剖析了使用docker-compose启动服务时常见的配置错误与权限问题,如文件挂载缺失、网络绑定错误等,提供了经过验证的避坑解决方案,旨在帮助运维和开发人员一次性成功部署。

weixin_29310605的博客 326

android开发之布局优化之include、ViewStub、merge使用与源码分析

在开发中UI布局是我们都会遇到的问题,随着UI越来越多,布局的重复性、复杂度也会随之增长。Android官方给了几个优化的方法,但是网络上的资料基本上都是对官方资料的翻译,这些资料都特别的简单,经常会出现问题而不知其所以然。这篇文章就是对这些问题的更详细的说明,也欢迎大家多留言交流。一、include概述:首先用得最多的应该是include,按照官方的意思,include就是为了解决重复定义相同布局

ZaneLove's blog 1075

C#面试题及详细答案120道(61-75)-- 多线程与异步

本文摘要了前后端面试题中关于线程与并发的核心知识点,包括线程与进程的区别(61题)、Thread/ThreadPool/Task的对比(62题)、线程安全实现方法(63题)、lock关键字的原理(64题)、Monitor类的进阶用法(65题)以及死锁的成因与避免(66题)。通过C#代码示例和表格对比,清晰展示了多线程编程的关键概念、应用场景及常见问题解决方案,适合开发者快速掌握面试高频考点。完整内容可访问专栏目录获取更多技术面试题解析。

大剑师兰特的GIS世界 1429

SA8295P QNX主机上电启动流程分析

嵌入式系统的启动过程对于确保系统正常运行至关重要。本文将详细分析SA8295P芯片在QNX主机上的上电启动流程,并提供相应的源代码示例。嵌入式系统的启动过程对于确保系统正常运行至关重要。本文将详细分析SA8295P芯片在QNX主机上的上电启动流程,并提供相应的源代码示例。以下是一个SA8295P QNX主机上电启动流程分析。

CodeMaven的博客 1230

Android 布局优化全解析:include、merge、ViewStub 实战与最佳实践(图文版)

目的推荐方式原因复用相同布局include简单可靠避免重复父布局merge减少层级延迟加载不常用布局ViewStub节省内存与渲染时间布局优化不是炫技,而是「让 UI 加载更快」的基础功。掌握includemergeViewStub的组合拳,你可以让应用启动速度提升、UI 更流畅。

qq_41821190的博客 892

服务器取证——服务器基础知识

服务器基础知识

记录并分享学习安全的知识点.. 2481

Android布局优化之ViewStub include merge使用与源码分析

Android布局优化之ViewStub include merge使用与源码分析

qq_44945094的博客 187

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Android性能优化系列之布局优化

在Android开发中,UI布局可以说是每个App使用频率很高的,随着UI越来越多,布局的重复性、复杂度也会随之增长,这样使得UI布局的优化,显得至关重要,UI布局不慎,就会引起过度绘制,从而造成UI卡顿的情况,本篇博客,我就来总结一下UI布局优化的相关技巧。 学会使用布局标签优化布局 (1)&lt;include&gt;标签  include标签常用于将布局中的公共部分提取出来供其他layo...

sxl_0305 577

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

include、merge、ViewStub与 性能优化

则用于延迟加载低频布局,只有真正需要显示时才进行 inflate,从而减少初始化阶段的 View 创建和内存开销。使用,去掉多余的根 ViewGroup,从而降低 View 树层级;自己不会生成 View,而是把内部 View 直接添加到父布局。例如多个页面都有相同的标题栏,可以将标题栏单独写成。用于把一个公共 XML 布局引入当前布局。主要用于公共布局复用;适合错误页、空数据页等。

Co_Hui的博客 205

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

终极Android布局优化指南:掌握merge、include和view stub的高级技巧

在Android开发中,**EffectiveAndroidUI布局优化**是提升应用性能和用户体验的关键。本文将深入探讨如何使用merge、include和view stub等高级布局技术,结合EffectiveAndroidUI项目的最佳实践,帮助开发者创建高效、可维护的UI界面。无论您是Android新手还是经验丰富的开发者,这些技巧都将显著提升您的应用质量。 ## 为什么Android布

gitblog_00468的博客 1053

setContentView调用流程(二) -将布局添加到mContentParent

到这里关于setContentView的执行流程以及与其相关的知识点就介绍完了,整体的流程不算复杂,我们在阅读源码的时候切记不要每一行代码都搞明白,只了解主流程即可,否则代码会看的头晕目眩,容易放弃,另外关于对源码的学习一定要自己去阅读源码,做笔记这样才能了解更加透彻且复习也快。如果大家有疑问或者发现错误,欢迎在下方留言,我会在第一时间回答!!

乐于分享,乐于讨论,欢迎大家积极讨论 810

Teable 快速本地部署教程:搭建属于你的 AI 电子表格协作平台

团队的业务数据一直寄存在在线表格 SaaS 里,换网、断网、合规审查都让人不踏实。Teable 是一个开源的 AI 电子表格协作平台,支持建表、公式计算、自动化和多人实时协作。这篇教程面向没有开发背景的你:跟着一套敲完,约二十分钟即可在本地服务器完成 Teable 部署,数据从此完全自管。 [![Teable 本地部署后的 AI 电子表格协作平台主界面](https://raw.gitcode.

gitblog_00125的博客 469

Android include与merge标签使用详解

Android include与merge标签使用详解

shuqiaoniu的博客 7259
上一篇: 一份年薪30万的Android面试宝典,附答案
超侠
博客等级 码龄10年 3粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值