
1. 为什么现在还要学RelativeLayout先想清楚使用场景1.1 一个被误解的老家伙先说个我自己的经历。前两年我接手维护一个老项目里面有一套复杂的个人中心页面最外层就是RelativeLayout。当时我已经习惯了ConstraintLayout第一反应是想重构。但等我真正把布局上的约束关系捋了一遍才发现这套界面有大量的底部对齐左边右边同时锚定根据控件A的位置决定控件B的需求用RelativeLayout表达起来反而是最直观的。后来我没动它只改了里面的几个嵌套层级。这就引出一个很朴素的问题RelativeLayout到现在还有没有学习的必要我的答案是有而且每个Android开发者都应该把它吃透。原因有三它是理解Android布局体系的一把钥匙。ConstraintLayout的很多约束概念其实就是从RelativeLayout的相对定位思路扩展出来的。搞懂RelativeLayout再看ConstraintLayout的constraint_toLeftOf、constraint_alignParentTop这些属性几乎零成本。老代码和开源项目里到处都是。GitHub上大量早期的开源项目、公司内部维护多年的代码库RelativeLayout使用率依然很高。读得懂、改得动是基本职业素养。某些场景下它依然是最优解。往深处说RelativeLayout的子View不需要像LinearLayout那样层层嵌套一个布局就能表达左上右下全对齐的关系而ConstraintLayout在这种简单对齐场景下反而显得配置啰嗦。工具链完整、写法直接是它至今没有被淘汰的理由。1.2 这篇文章的受众和阅读方式我默认你至少有Android XML布局的基础知道怎么新建一个布局文件看得懂match_parent和wrap_content的区别。如果你完全零基础也没关系我会把RelativeLayout的每一个核心属性都拆开讲配合可运行的代码片段和实际界面效果说明。你可以把这篇文章当一份查漏补缺的复习资料也可以当成第一次系统学习RelativeLayout的入门教程。核心就一件事看完之后你拿到一个界面原型能第一时间判断该不该用RelativeLayout并且能熟练写出对应的XML。这篇内容还会穿插一些我实际开发中踩过的坑这些坑在官方文档里可查不到。2. RelativeLayout的底层逻辑两个参照系看懂全部属性2.1 布局的锚点思维RelativeLayout翻译过来就是相对布局。它和LinearLayout最本质的区别在于LinearLayout是排队子View按照顺序一个挨一个排RelativeLayout是定位每个子View都相对于某个锚点来决定自己的位置。锚点可以是整个父容器也可以是另一个子View。听起来简单但很多人写RelativeLayout写不好就是因为没把锚点这件事想清楚。我见过不少初级开发者写出这样的代码想做一个居中标题用了layout_centerInParenttrue同时又写了layout_alignParentToptrue然后对着屏幕陷入沉思为什么标题跑到了顶部而不是居中这就涉及RelativeLayout一个基本特性同一个子View的多个定位属性是可以叠加生效的它们不是互斥关系。alignParentTop把View的上边缘对齐父容器顶部centerInParent要求View在父容器里水平和垂直都居中这两个条件同时成立系统最终会把View放在顶部居中——是的垂直方向被alignParentTop锁死了centerInParent只在未被约束的方向生效。这种约束叠加的理解方式是掌握相对布局的第一步。2.2 相对父容器定位的属性群RelativeLayout把定位属性分成两大类一类相对于父容器另一类相对于兄弟控件。先看相对于父容器的这一组也是最常用的一组layout_alignParentTop 上边缘对齐父容器顶部 layout_alignParentBottom 下边缘对齐父容器底部 layout_alignParentLeft 左边缘对齐父容器左侧 layout_alignParentRight 右边缘对齐父容器右侧 layout_centerHorizontal 水平居中 layout_centerVertical 垂直居中 layout_centerInParent 水平垂直居中每个属性的作用都如其名但有几个细节值得多说两句。第一个细节layout_alignParentBottom和layout_centerInParent同时用会怎样结果是View相对父容器垂直居中的同时下边缘又对齐父容器底部。如果View高度是固定值它就会往下沉如果View高度是wrap_content那么它的中心会被拉到父容器垂直中心同时下边缘对齐底部这两个约束同时要求View的底部等于父容器底部、View的中心等于父容器中心——唯一的办法是View的高度为0所以实际渲染时会出现难以预料的结果。这个组合基本属于逻辑上互相矛盾的配置实际开发中看到这种写法大概率是开发者没想清楚要什么效果。第二个细节这些属性名称里的Parent指的是父容器也就是RelativeLayout本身。如果你把RelativeLayout嵌在LinearLayout里alignParentTop锚定的依然是RelativeLayout内部顶部而不是外面的LinearLayout——除非外层LinearLayout的orientation和gravity恰好把它推到某个位置。锚定的坐标系永远作用于直接父容器。这一组属性在写全屏弹窗、底部操作栏、顶部标题栏时非常高效。举个我经常用的例子一个右上角关闭按钮只需要三行ImageView android:idid/btn_close android:layout_widthwrap_content android:layout_heightwrap_content android:layout_alignParentToptrue android:layout_alignParentRighttrue android:srcdrawable/ic_close /放在任何RelativeLayout里它都自动待在右上角完全不需要处理不同屏幕宽度下的位置计算。2.3 相对兄弟控件定位的属性群这组属性是RelativeLayout真正有独特价值的地方。先记住一个总原则凡是带layout_to或layout_align开头、后面跟Left/Right/Top/Bottom、且值写了一个View的id的属性都是锚定另一个子View。核心属性如下layout_toLeftOf 本View的右边缘在指定View的左边缘左侧 layout_toRightOf 本View的左边缘在指定View的右边缘右侧 layout_above 本View的底部在指定View的顶部之上 layout_below 本View的顶部在指定View的底部之下 layout_alignLeft 本View的左边缘与指定View的左边缘对齐 layout_alignRight 本View的右边缘与指定View的右边缘对齐 layout_alignTop 本View的上边缘与指定View的上边缘对齐 layout_alignBottom 本View的下边缘与指定View的下边缘对齐 layout_alignBaseline 本View的baseline与指定View的baseline对齐layout_toRightOf是出现频率最高的需求场景文字左边放一个图标按钮左边放一个输入框标签右边放一个数值全部用它。字面上看layout_toRightOf的意思是本View在指定View的右边但注意它的精确语义是本View的左边缘位于指定View的右边缘的右侧——这是**不重叠关系**而不是贴住关系。两个View之间要留间距就用layout_marginLeft比如android:layout_marginStart8dp。这组属性还有一个优点Anchor View锚定参照物的位置一旦确定被锚定的View会自动跟随变化不需要额外的代码。实际项目里动态增删View时这个特性省了一大堆重新测量的逻辑。2.4layout_alignBaseline文字对齐的最后一块拼图很多人写表单、写列表项时遇到过这样的问题一行里左边一个TextView右边一个TextView用layout_alignTop对齐结果两边的文字基线就是差那么几个像素怎么调都不舒服。这是因为TextView的高度不只包含文字本身还有fontPadding和行高。用layout_alignTop只能对齐View的上边缘不能保证文字对齐。正确的做法是用layout_alignBaselineRelativeLayout android:layout_widthmatch_parent android:layout_heightwrap_content TextView android:idid/label android:layout_widthwrap_content android:layout_heightwrap_content android:text价格 / TextView android:idid/value android:layout_widthwrap_content android:layout_heightwrap_content android:layout_toRightOfid/label android:layout_alignBaselineid/label android:text199.00 / /RelativeLayout这样两个TextView的baseline文字基线严格对齐即使一个字号大一个字号小视觉上也始终是整齐的。这个细节是真正用过RelativeLayout的人才会注意到的。3. 实战拆解用相对布局搭一个商品详情页头部3.1 需求分析和布局设计理论看再多不动手等于白看。我挑一个电商类App常见的商品详情页头部来做完整拆解。需求描述最上面是一个占满顶部区域的商品大图图片的左下角叠加一个包邮标签图片右下角叠加一个收藏按钮大图下方是一行商品名称文字长度不固定最多两行名称下方是价格信息价格左边有一个促销角标这个需求看似简单但如果你用LinearLayout来写大图上的标签和按钮需要FrameLayout来完成叠加价格和角标又要额外嵌套一层Horizontal方向的LinearLayout至少三层嵌套才能搞定。用RelativeLayout一个布局就能全部表达RelativeLayout android:layout_widthmatch_parent android:layout_heightwrap_content !-- 商品大图 -- ImageView android:idid/image android:layout_widthmatch_parent android:layout_height200dp android:scaleTypecenterCrop android:srcdrawable/product / !-- 包邮标签相对父容器左下角 -- TextView android:idid/tag_free_shipping android:layout_widthwrap_content android:layout_heightwrap_content android:layout_alignParentLefttrue android:layout_alignParentBottomtrue android:layout_margin8dp android:backgrounddrawable/bg_tag_orange android:paddingLeft6dp android:paddingRight6dp android:text包邮 android:textColor#FFFFFF android:textSize12sp / !-- 收藏按钮相对大图右下角 -- ImageView android:idid/btn_favorite android:layout_width32dp android:layout_height32dp android:layout_alignParentRighttrue android:layout_alignBottomid/image android:layout_margin8dp android:srcdrawable/ic_favorite / !-- 商品名称在大图下方 -- TextView android:idid/title android:layout_widthmatch_parent android:layout_heightwrap_content android:layout_belowid/image android:layout_marginLeft12dp android:layout_marginRight12dp android:layout_marginTop8dp android:ellipsizeend android:maxLines2 android:text这是一段很长的商品名称文本用来演示相对布局中TextView的实际换行效果 android:textColor#333333 android:textSize16sp / !-- 促销角标相对商品名称左边 -- TextView android:idid/tag_promo android:layout_widthwrap_content android:layout_heightwrap_content android:layout_alignBaselineid/title android:layout_toLeftOfid/title android:backgrounddrawable/bg_tag_red android:paddingLeft4dp android:paddingRight4dp android:text促销 android:textColor#FFFFFF android:textSize12sp / !-- 价格在商品名下方促销角标右边 -- TextView android:idid/price android:layout_widthwrap_content android:layout_heightwrap_content android:layout_belowid/title android:layout_marginLeft12dp android:layout_marginTop4dp android:text199.00 android:textColor#FF2D2D android:textSize20sp android:textStylebold / /RelativeLayout注意我在这里用一个稍作妥协的方案来演示tag_promo用的是layout_alignBaseline和layout_toLeftOf同时锚定title而title本身是layout_belowid/image整条链路的参照关系是层层递进、有据可循的。3.2 每一行代码背后的选择逻辑刚才的XML里几个决定值得单独拿出来说为什么收藏按钮用的是layout_alignParentRightlayout_alignBottomid/image而不是layout_alignParentBottom从实现效果上看大图的底部就是父容器相对布局的底部两个写法效果一致。但语义上layout_alignBottomid/image更明确按钮是贴住图片的如果以后在图片下方加了一个高度为16dp的优惠券区域、且原RelativeLayout的height是wrap_content按钮就会跟着优惠券区域往下沉而不是停留在原图片底部。锚定具体View比锚定父容器更抗布局变更。为什么包邮标签不锚定大图因为大图是match_parent宽、200dp高它的左边缘和底边缘与父容器完全重合所以锚定父容器和锚定大图没有差别。但如果大图改成了wrap_content或者加了scaleType调整锚定对象不同就会产生差异。我的建议是视觉上确实要贴住哪个对象就锚定哪个对象别省这一行。为什么促销角标要用layout_toLeftOfid/title而不是放在title内部用drawableLeft因为角标需求是独立的、可能有自己的点击事件和文本内容没有关系。drawableLeft虽然也能画出一个小图标但无法独立控制它的点击区域、背景形状和间距维护性差。3.3 看看最终效果的等价关系你可以把上面这个布局在Android Studio的Preview里跑一下再看一眼布局层级结构整个页面只有一个RelativeLayout节点下面全是平级的子View没有任何嵌套。这就是相对布局最大的结构优势扁平化。嵌套深度直接影响性能。Android的measure和layout过程是递归执行的嵌套越深一次布局计算的耗时越大特别是在列表滚动时会被放大。官方Performance文档专门点过尽量保持布局层级扁平。RelativeLayout用一张平面上的锚点关系网取代了多层级容器这个优势在复杂头部这类场景里体现得非常直接。4. RelativeLayout、LinearLayout与ConstraintLayout到底怎么选4.1 不同场景下的取舍标准很多人以为RelativeLayout已经过时了写新界面就应该无脑上ConstraintLayout。这话说对了一半但忽略了一个关键点布局选型要考虑维护成本、团队认知和具体需求的复杂度工具本身没有绝对的好坏。我做个简单的对比方便你按场景选择布局类型核心优势典型劣势最佳使用场景LinearLayout结构简单线性排列直觉化支持weight比例分配复杂界面嵌套深层级膨胀表单、列表项、按钮组等线式排列RelativeLayout扁平化描述锚点关系相对定位代码量小属性语义多初步学习成本高多重约束叠加容易出现不可预期结果头部区域、全屏弹窗、底部栏、图标叠层ConstraintLayout约束能力最强可视化编辑完善支持链、比例、Guideline等高级能力简单场景配置繁琐XML冗长过度设计反而难维护复杂页面、自适应布局、需要高性能的动态界面这个表是我的个人实践经验总结不是官方定论。具体到选型时我通常遵循三个标准如果这个界面可以用LinearLayout平铺完成且嵌套不超过两层优先LinearLayout。骨架简单时用简单工具。如果界面里有明显的叠层和多向锚定需求——比如某个View要贴住另一个View的右下同时还要对齐父容器的顶部——直接考虑RelativeLayout或ConstraintLayout。这种需求用LinearLayout硬凑会付出嵌套代价。如果页面有动态伸缩、按比例分配空间、或者复杂的对位需求用ConstraintLayout。它的Guideline和Barrier等特性确实是RelativeLayout不具备的。4.2 一个用RelativeLayout反而更好的真实案例我参与维护过一个直播间礼物面板界面需求是这样的一个全屏半透明遮罩中央区域有一个礼物列表列表底部固定一个充值按钮按钮上方一排礼物Tab。原来的实现是外层FrameLayout内层两个RelativeLayout分居上下两个RelativeLayout里面又套了LinearLayout若干。总层级达到五层。列表滑动时部分中低端机型有明显的掉帧。后来我重构时只保留了一个RelativeLayout作为根节点礼物Tab锚定面板底部layout_alignParentBottom、列表在Tab上方layout_above、充值按钮再锚定Tab的底部下方。层级从五层压到两层刷新的measure耗时肉眼可见地降了下来。这个案例想表达的是RelativeLayout并没有淘汰它在某个具体的层级约束问题里甚至比ConstraintLayout更干脆利落。因为RelativeLayout的属性系统就是围绕相对锚定设计的你在写layout_below、layout_toRightOf、layout_alignParentBottom时思路是直来直去的。4.3 新手最容易陷入的嵌套陷阱很多从LinearLayout入门的人容易形成惯性先竖着排一根LinearLayout发现左右排不下了再在中间嵌一根水平LinearLayout。这样一层层叠下去直到写出一棵圣诞树。问题是LinearLayout嵌套的层级成本比RelativeLayout和ConstraintLayout都要高因为每个LinearLayout在measure时都要遍历子View嵌套层级每增加一层整个布局树的计算量就显著放大。RelativeLayout强烈建议用于替代这种多方向排列靠嵌套的写法。你只需要在根布局里定义好每个View之间的锚点关系层级是平的阅读者一眼就能看出谁在谁的右边谁在谁的下面维护起来省心得多。5. RelativeLayout的性能误区和踩坑记录5.1 一个流传很广的性能差传言真相是什么说到RelativeLayout总绕不开一个传言RelativeLayout会对子View进行两次measure性能不如LinearLayout。这个说法有历史背景在Android 2.x时代确实存在当时RelativeLayout的measure逻辑会对部分子View额外测量以保证锚定关系正确。但随着Android版本迭代这一点早已经大幅改进了。在Android 4.0之后系统对RelativeLayout的measure过程做了大量优化现代设备上只要你的RelativeLayout层级不深、子View数量不过多性能差异几乎可以忽略。那为什么项目里RelativeLayout偶尔还是很卡我观察到的真正原因往往不是RelativeLayout本身而是内部嵌套了多层其他布局导致整体层级膨胀子View数量过多超过十几个单个布局承担了太多职责在列表项中使用带复杂测量的RelativeLayout且列表滚动频繁触发measure优化思路是一个RelativeLayout只承担一类明确的布局职责子View数量控制在合理范围内。如果发现一个RelativeLayout里有二十几个子View说明这个布局该拆了。5.2wrap_content和match_parent的神秘失踪情况是这样的RelativeLayout根节点加上android:layout_heightwrap_content里面有一个子View设置layout_alignParentBottomtrue。你会发现在某些情况下子View并没有出现在父容器的底部甚至父容器看起来塌了。原因要从RelativeLayout的测量机制说起。RelativeLayout的wrap_content高度需要根据所有子View的位置关系来推算但子View的alignParentBottom是指向父容器底的——这里形成了一个循环依赖父容器高度依赖于子View子View位置依赖于父容器高度。系统解决不了这个死循环实际执行时alignParentBottom会被忽略或者高度计算产生意外结果。经验法则如果子View用了layout_alignParentBottom父RelativeLayout的高度就固定用match_parent或者明确指定值不要用wrap_content。反之如果父容器是wrap_content尽量用layout_below、layout_above这类锚定兄弟控件的属性而不是锚定父容器。5.3layout_gravity在RelativeLayout中不生效这是很多从LinearLayout转过来的人踩过的第一坑。layout_gravity是LinearLayout和FrameLayout的属性用来控制子View在父容器里的对齐方式。RelativeLayout里根本没有这个概念子View的定位完全由锚点属性控制。我见过有人写出这样的代码RelativeLayout ... TextView android:idid/title android:layout_widthwrap_content android:layout_heightwrap_content android:layout_gravitycenter_horizontal android:text标题 / /RelativeLayout结果TextView安静地待在左上角完全无视layout_gravity。正确做法是改用android:layout_centerHorizontaltrue或者用layout_centerInParenttrue实现完全居中。类似的layout_weight只属于LinearLayoutRelativeLayout里写了也不生效。布局系统里每种布局都有自己的一套接口跨布局用属性就是在写无效代码而且编译器不一定报错。5.4layout_margin和锚定属性的顺序陷阱XML属性在标签里的书写顺序不会影响布局结果所以下面这段代码是合法的TextView android:idid/label android:layout_widthwrap_content android:layout_heightwrap_content android:layout_marginLeft16dp android:layout_toRightOfid/icon /但很多人被误导以为margin写在toRightOf后面会先定位再加边距写在前面就加完边距再定位其实没有这个区别。RelativeLayout的规则是锚定属性和margin属性独立作用于最终位置。layout_toRightOfid/icon确定了本View的左边在icon的右边layout_marginLeft16dp在这基础上再向左增加16dp间距。两个属性互不干扰无论书写顺序如何结果都一样。5.5 动态添加View时记住锚点必须先存在这是开发过程中最容易写完不报错运行就崩溃的一个点。RelativeLayout里子View锚定另一个View时被锚定的View必须在布局中有明确的id。如果锚定的id在运行前不存在比如动态创建的View还没add系统会抛ClassCastException或Resources.NotFoundException。动态添加的场景要养成两个习惯// 动态创建锚定目标View TextView title new TextView(context); title.setId(View.generateViewId()); // 显式指定一个可用的id rl.addView(title); // 再创建依赖View锚定它 TextView price new TextView(context); RelativeLayout.LayoutParams params new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.BELOW, title.getId()); rl.addView(price, params);View.generateViewId()是API 17引入的如果需要兼容更低版本手动定义id即可。顺序上先添加锚定目标再添加依赖View避免measure阶段找不到锚点。5.6 布局嵌套过深时的测量耗时问题最后分享一个性能定位方法。如果你负责的项目里有页面明显卡顿可以用Android Studio的Layout Inspector打开布局层级图看最浅到最深的一条链上有多少层。Normal标准是首选布局层级尽量控制在三层以内。RelativeLayout在这方面天生有优势。但注意RelativeLayout再强也架不住你在里面又套三四个RelativeLayout。扁平化是目标不是初始状态写完布局最好回头检查一遍凡是能用锚点解决的嵌套一律打开层级图确认是否真的扁平了。6. 从RelativeLayout到ConstraintLayout路径比想象中平滑6.1 属性映射表把相对布局的经验迁移过去如果你已经仔细理解了前文所有RelativeLayout属性现在学ConstraintLayout会非常快因为两者的底层思路是同一个爹——都通过约束关系描述位置只是ConstraintLayout把约束边界做得更精细、能力边界更宽。RelativeLayout属性ConstraintLayout对应写法layout_alignParentToptrueapp:layout_constraintTop_toTopOfparentlayout_alignParentBottomtrueapp:layout_constraintBottom_toBottomOfparentlayout_alignParentLefttrueapp:layout_constraintStart_toStartOfparentlayout_alignParentRighttrueapp:layout_constraintEnd_toEndOfparentlayout_centerInParenttrue同时设置Top_toTopOfparentBottom_toBottomOfparentStart_toStartOfparentEnd_toEndOfparentlayout_toRightOfid/viewapp:layout_constraintStart_toEndOfid/viewlayout_toLeftOfid/viewapp:layout_constraintEnd_toStartOfid/viewlayout_aboveid/viewapp:layout_constraintBottom_toTopOfid/viewlayout_belowid/viewapp:layout_constraintTop_toBottomOfid/viewlayout_alignBaselineid/viewapp:layout_constraintBaseline_toBaselineOfid/viewlayout_alignStartid/viewapp:layout_constraintStart_toStartOfid/view这张表不是让你死记硬背而是让你建立映射直觉RelativeLayout里的align是对齐边缘到了ConstraintLayout里就变成toStartOf依赖另一个View的边RelativeLayout里的toRightOf是不重叠到了ConstraintLayout就是Start_toEndOf。语义一脉相承。6.2 什么时候迁移什么时候保持不动很多人跟我聊搬迁的事其实迁移不是必须的。我的判断标准是页面逻辑简单、改动频率低比如一个弹窗、一个页脚、一个固定结构的小部件用RelativeLayout写着挺好迁移收益微乎其微。页面变动频繁、有大量自适应需求比如首页、详情页、多尺寸平板适配考虑迁移到ConstraintLayout利用它的链、百分比、Guideline降低适配成本。团队平均水平决定一切如果团队里大部分人对ConstraintLayout不熟写着写着就变成了代码能跑但约束一团乱麻那还不如老老实实RelativeLayout。工具再强人用不明白反而坏事。我个人经历是真正让我坚定选择ConstraintLayout的场景往往是需要把一个View放在两个View的中间偏左33%的位置这类精确比例的约束或者需要一行代码实现多个View的按比例分配这些确实是RelativeLayout做不到的。6.3 学习路线建议别跳过RelativeLayout我面试候选人的时候如果对方说只写过ConstraintLayout不怎么了解RelativeLayout我通常还会多问几个关于锚点、约束、测量时机的问题。原因是我发现RelativeLayout的每一组属性本质上都在训练约束建模的思维方式。你能清楚地回答这个View为什么在这里、换个屏幕宽度它应该怎么动才是真正的布局能力。建议的学习顺序是这样的先用RelativeLayout复习锚点概念把前文两张属性群理解透彻。动手写三个实战页面一个底部操作栏、一个右上角悬浮按钮、一个图片文字价格的商品卡。打开Layout Inspector看这三个页面的层级树体会扁平化带来的性能收益。再把同样的页面用ConstraintLayout实现一遍对照属性映射表体会约束概念的演化。这样走完一遍你对Android布局系统的理解会是整体的而不是零散的几个API。以后无论看老代码还是写新架构心里都有数。7. 关于RelativeLayout的隐藏收益写布局时更容易做视觉对齐这里写一点或许可以和单纯学布局区分开的内容——我是后来带新人才注意到的练熟RelativeLayout之后你对照设计稿写界面的速度会明显快于只用LinearLayout的人。因为在Sketch/Figma上几乎所有设计元素都有明确的相对位置关系这个图标在文字的右边、这个标签在图片的底部天然就是RelativeLayout的语言。每次拿到设计稿我习惯先在纸上画出元素的锚点关系图中心点是谁底部谁对齐左边谁在谁的右边这个过程不超过五分钟但能避免打开编辑器后反复调坐标的无效劳动。严格说这种先建模再编码的习惯就是RelativeLayout学习赐予你的副产品而且是挺值钱的那种。如果只能分享一个心得我会说布局写不好的根源一般不是工具不会而是没想清楚谁在谁的哪里这句话。RelativeLayout强迫你把这句话写明白。最后留个实际的作业试着用RelativeLayout重写一个你手机里最常用的App页面比如底部导航栏、搜索框按钮、个人中心卡片然后打开Layout Inspector对比一下现在的层级和原来的实现大多数时候你会看到明显的层级瘦身。做完这步你对RelativeLayout的理解就不仅仅是会用而是用得值。