1. 从零开始为什么布局是Android开发的基石如果你刚打开Android Studio看着那个空白的activity_main.xml文件可能会有点懵。这玩意儿不就是拖拖拽拽放几个按钮和文本框吗我刚开始学的时候也是这么想的直到我接手了一个别人写的项目那个布局文件打开后代码嵌套了七八层各种ConstraintLayout的约束线像蜘蛛网一样改一个地方整个界面都崩了。那一刻我才真正明白布局远不是拖拽那么简单它是你App的骨架决定了用户体验的第一印象和操作流畅度。简单来说布局Layout就是用来定义Android应用用户界面UI结构的一套规则和容器。它告诉系统“嘿这个TextView应该放在屏幕顶部那个Button要在屏幕右下角并且它们的大小要随着屏幕旋转自动调整。” 在Android Studio里我们主要通过两种方式来构建布局一种是直接在可视化的设计编辑器Design Editor里拖放组件另一种是手动编写XML代码。前者适合快速原型和直观调整后者则提供了更精确、更强大的控制能力尤其是在处理复杂界面和动态效果时。为什么我要花这么大篇幅跟你聊这个看似基础的东西因为据我观察至少一半的Android新手遇到的“诡异”问题——比如按钮点不了、图片显示不全、在不同手机上界面错乱——其根源都出在布局上。理解布局不仅仅是学会用几个LinearLayout或ConstraintLayout更是要理解Android系统如何测量Measure、布局Layout、绘制Draw你的视图树。这决定了你的App是流畅顺滑还是卡顿掉帧。这篇内容我会带你超越“拖拽组件”的层面深入到Android布局的核心机制、各种常用布局的实战选型以及那些官方文档里不会写的、我踩过无数坑才总结出来的调试与优化技巧。无论你是刚安装好Android Studio的新手还是已经写过几个Demo但总被界面问题困扰的开发者相信都能找到你需要的东西。2. 核心布局管理器深度解析不止是排列控件当你新建一个项目默认的activity_main.xml里很可能是一个ConstraintLayout。但Android提供的布局管理器远不止这一种。选择哪种布局就像木匠选择工具用对了事半功倍用错了就得返工。下面我们来拆解几个最核心、最常用的布局重点讲清楚它们的设计哲学、适用场景和那些容易踩的坑。2.1 LinearLayout简单直白的线性思维LinearLayout线性布局是最好理解的布局之一。它把里面的子视图View按水平horizontal或垂直vertical方向一个接一个地排列。它的属性很简单但用好了也非常强大。核心属性与权重的魔力除了方向orientationLinearLayout最精髓的属性是layout_weight权重。这个属性解决了线性布局中“按比例分配剩余空间”的经典需求。很多新手对weight的理解有偏差这里必须讲透。假设我们有一个水平方向的LinearLayout里面放了两个Button。LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationhorizontal Button android:layout_width0dp android:layout_heightwrap_content android:layout_weight1 android:text按钮1 / Button android:layout_width0dp android:layout_heightwrap_content android:layout_weight2 android:text按钮2 / /LinearLayout关键点来了layout_weight生效的前提是该方向上的layout_width对于水平布局或layout_height对于垂直布局必须设置为0dp。系统计算空间的步骤是先给所有设置了weight的子View分配它们声明的尺寸比如wrap_content或固定值。计算剩余空间。按照weight的比例将剩余空间分配给这些子View。如果你把layout_width设为wrap_content系统会先按内容大小给按钮分配空间可能已经占满了weight就失去了作用。所以记住这个公式LinearLayoutweight 对应尺寸设为0dp。实战心得与坑性能与嵌套地狱LinearLayout在测量布局时相对高效但千万不要用它来实现复杂的多行多列界面。我见过最夸张的代码用七八层嵌套的LinearLayout来实现一个九宫格导致界面渲染慢如蜗牛。对于复杂布局这是大忌。baselineAligned的陷阱这个默认开启的属性会让所有子View的文本基线对齐。如果你在一个水平LinearLayout里放了一个ImageView和一个TextView因为ImageView没有文本基线可能会导致TextView的位置很奇怪。在不需要基线对齐时记得设置android:baselineAlignedfalse。适用场景简单列表项、顶部/底部栏Tab Bar、等分按钮组等单行或单列的布局。它是RecyclerView的ListView时代最常用的项布局。2.2 RelativeLayout通过关系定位的“相对论”RelativeLayout相对布局允许你通过视图之间的相对位置关系来定位比如“在A的右边”、“在B的底部”、“与父容器顶部对齐”。它在早期Android开发中非常流行因为可以减少嵌套。核心规则定位依赖于两类属性相对于父容器如android:layout_alignParentToptrue与父容器顶部对齐。相对于其他视图需要先为目标视图定义一个IDid/view_id然后使用如android:layout_toRightOfid/view_id在指定视图的右侧。为什么它逐渐被ConstraintLayout取代尽管RelativeLayout很灵活但它有几个硬伤可读性差当视图间关系复杂时XML文件会变得难以阅读和维护。你需要来回查找ID来确定位置关系。性能隐患RelativeLayout为了确定每个视图的位置可能需要进行两次测量过程measure pass这在复杂界面中会影响性能。缺乏约束的灵活性它的相对关系是二元的是或否而ConstraintLayout的约束可以是有比例、有偏差的更能适应不同尺寸的屏幕。当前适用场景现在除非维护遗留代码在新项目中我已经很少主动使用RelativeLayout了。它可能在一些非常简单的、只有一两个相对定位需求的场景中还有一席之地但ConstraintLayout几乎能完全覆盖并做得更好。2.3 ConstraintLayout现代Android布局的绝对主力这是目前Google力推的、功能最强大的布局管理器。它继承了RelativeLayout的相对定位思想但将其发展成了一个更强大、更灵活的约束系统。它的目标是用扁平化的视图层次减少嵌套来实现复杂的布局从而提升性能。约束的核心思想每个视图的边左、上、右、下和基线Baseline都可以与另一个视图的边、父容器的边或者一条不可见的引导线Guideline建立约束。视图的位置就由这些约束共同决定。必须掌握的关键特性链条Chains这是实现视图组整体行为的神器。选中多个视图右键就能创建水平或垂直链条。链条可以设置不同的样式spread默认均匀分布剩余空间。spread_inside第一个和最后一个视图贴在两端中间均匀分布。packed所有视图抱团在一起可以整体设置偏移bias。 链条行为是LinearLayout难以优雅实现的比如让三个按钮整体在父容器中水平居中用packed链。比例约束与偏移Bias当一个视图的左右或上下两边同时约束到父容器时你可以通过layout_constraintHorizontal_bias水平偏移来调整它在水平方向上的位置比例。例如bias0.3表示距离左边约束的距离占总约束宽度的30%。还可以设置宽高比通过app:layout_constraintDimensionRatio比如H,16:9表示宽高比16:9前提是至少有一个维度设置为0dp。屏障Barrier与组GroupBarrier一个虚拟的、不可见的参考线它的位置会根据所“监视”的一组视图的特定边如右边界自动调整始终位于这些边界的最外侧。这完美解决了“让一个视图始终位于多个不定长文本视图的右侧”这类动态布局问题。Group可以同时控制一组视图的可见性visibility而无需分别设置每个视图。但它只控制可见性不参与布局定位。实战避坑指南match_constraint与0dp在ConstraintLayout中如果你想让一个视图的宽度填满约束之间的空间应该设置android:layout_width0dp官方现在更推荐称为match_constraint。这不同于match_parent。match_parent会忽略约束直接匹配父容器大小。约束缺失导致的“飘走”如果一个视图没有在某个方向上如水平方向建立至少两个相反的约束左和右它就会在布局编辑器中“飘”到坐标(0,0)位置或者在运行时行为不确定。确保每个视图在横竖两个方向上都至少有一个约束是使用ConstraintLayout的第一要务。过度使用约束导致性能下降虽然ConstraintLayout设计上是为了性能但如果你建立了非常复杂、环环相扣的约束网络测量过程也会变慢。对于列表项RecyclerView的Item这种需要频繁创建和绑定的视图要尤其注意约束的简洁性。2.4 其他布局管理器速览FrameLayout最简单粗暴的布局所有子视图默认堆叠在左上角。常用作容器一次只显示一个子视图比如Fragment的容器或者配合include标签复用布局。通过android:layout_gravity可以调整子视图的位置。GridLayout网格布局可以定义行数列数将子视图放入网格中。它比用LinearLayout嵌套实现网格要高效但功能相对固定不如后面提到的RecyclerViewGridLayoutManager灵活所以在现代开发中直接使用较少。TableLayout以表格形式排列继承自LinearLayout。每个TableRow代表一行。它的使用非常局限样式难以定制基本已被更灵活的方案取代。3. 编写与调试布局XML从能用走向优雅掌握了布局管理器我们就要开始动手写XML了。Android Studio提供了强大的可视化工具但真正的高手一定是“手写”和“预览”结合。这一章我们来聊聊如何高效地编写和调试布局XML代码。3.1 设计编辑器Design Editor的双刃剑Android Studio的设计视图Design和蓝图视图Blueprint非常直观。你可以直接从Palette拖拽组件在属性窗口Attributes调整参数并通过鼠标拖拽来建立约束。善用它的优点快速原型在构思界面时用拖拽的方式快速搭建出雏形比直接写代码快得多。直观建立约束在ConstraintLayout中用鼠标按住视图边缘的锚点拖到另一个视图或父容器的边缘就能快速创建约束比手写属性直观。多配置预览在预览窗口你可以同时查看不同屏幕尺寸、不同语言、不同主题下的布局效果这对于适配工作至关重要。警惕它的陷阱生成冗余代码设计编辑器有时会生成一些不必要的属性或者使用绝对定位tools:layout_editor_absoluteX这些代码只在预览时有效运行时会被忽略但会污染你的XML文件。务必定期切换到代码视图Code检查并清理这些tools:命名空间的属性。约束理解不深过度依赖拖拽可能会导致你对约束关系的理解停留在表面。当遇到复杂布局或需要动态调整时你会无从下手。我的建议是先用设计编辑器搭出大概然后切换到代码视图去理解和微调每一个约束属性。性能预览不真实设计编辑器中的流畅度不代表真机或模拟器上的性能。复杂的可视化布局在编辑器里可能也会卡顿但这不完全是你的布局问题。3.2 手写XML的核心技巧与最佳实践1. 属性顺序与格式化保持XML的整洁可读至关重要。我推荐一个属性分组排序的习惯Android Studio的“Reformat Code”功能可以辅助android:id— 视图的唯一标识放在最前。layout_width/layout_height— 尺寸这是布局的基础。布局相关的特定属性如orientation,constraintXXX等。视图内容属性如text,src,background。样式和主题属性如style,textAppearance。事件处理属性如onClick但更推荐在代码中设置。tools:命名空间属性 — 仅用于预览的放在最后。2. 善用tools:命名空间进行预览增强tools:属性在应用运行时会被完全忽略是开发者的利器。tools:text预览文本在设计视图显示假数据避免界面空荡荡。tools:context.MainActivity在根布局声明让预览能应用对应Activity的主题。tools:listitem/tools:listHeader在ListView或RecyclerView的布局中预览项样式。tools:showInlayout/another_layout当这个布局被include到另一个布局时在此布局中可以直接预览它在父布局中的效果。3. 布局的复用include与mergeinclude用于将公共的布局片段抽取到一个独立的XML文件中然后在多个地方引用。这符合DRYDon‘t Repeat Yourself原则便于维护。!-- common_toolbar.xml -- androidx.appcompat.widget.Toolbar ... ... /Toolbar !-- 在activity_main.xml中引用 -- include layoutlayout/common_toolbar android:idid/my_toolbar android:layout_widthmatch_parent android:layout_height?attr/actionBarSize/注意你可以通过include标签覆盖被引入布局根视图的layout_属性如layout_width但最好给被引入的根视图一个合理的默认值。merge用于优化include时的视图层级。当被include的布局文件的根标签是merge时这个标签本身不会在视图树中创建一层它的子视图会直接合并到父布局中。这能减少一层不必要的ViewGroup提升性能。!-- common_buttons_merge.xml -- merge xmlns:androidhttp://schemas.android.com/apk/res/android Button android:idid/ok .../ Button android:idid/cancel .../ /merge !-- 在父布局中include两个Button会直接成为父布局的子View -- include layoutlayout/common_buttons_merge/使用merge的关键是被引入的布局不需要一个独立的父容器来管理其子视图的布局。3.3 布局调试当界面不按预期显示时界面出了问题别急着乱改代码。有一套系统的排查方法第一步检查XML语法与约束完整性打开activity_main.xml切换到“Code”视图看Android Studio有没有报红语法错误。对于ConstraintLayout检查每个视图是否在横竖方向都有约束。可以在设计视图点击“Show Constraints”按钮像铁链的图标来高亮显示所有约束。第二步使用布局检查器Layout Inspector这是Android Studio内置的神器可以直接连接到正在运行的App模拟器或真机以可视化树形结构查看完整的视图层级、每个视图的属性以及它在屏幕上的边界框。怎么用运行你的App - 点击Android Studio底部工具栏的“Layout Inspector”图标。看什么视图树Component Tree看嵌套是否过深有没有多余的视图层级。属性列表选中某个视图查看它所有属性的运行时实际值这比看XML代码更准确。3D视图可以旋转视角查看视图的层叠关系对于发现“布局重叠”问题特别有用。第三步开启调试选项显示布局边界在开发者选项或通过ADB命令adb shell setprop debug.layout true开启会在屏幕上用彩色线框画出每个视图的边界。这能一眼看出哪个视图超出了预期范围。强制使用英文布局在开发者选项中开启“Force RTL layout direction”可以快速检查你的布局在从右向左RTL语言下的适配情况。第四步查看日志布局测量和绘制过程中的严重错误如onMeasure或onLayout抛出异常会在Logcat中打印出来。过滤View相关的Tag寻找线索。4. 性能优化与高级适配让你的布局快且稳一个好看的布局如果滑动起来卡顿或者在不同设备上显示错乱依然是失败的。这一章我们深入布局的性能瓶颈和适配策略。4.1 过度绘制与布局层级优化过度绘制Overdraw指屏幕上一个像素在单帧内被绘制了多次。例如一个不透明的蓝色按钮放在一个不透明的红色背景上红色背景的绘制就是完全浪费的。过度绘制会严重消耗GPU资源导致卡顿。如何检测在开发者选项中开启“调试GPU过度绘制”颜色越深特别是红色的区域表示过度绘制越严重。优化手段减少背景移除不必要的background。特别是根布局或全屏背景确保它是有必要的。使用android:outlineSpotShadowColor和android:outlineAmbientShadowColor替代复杂背景实现阴影API 28而不是用带阴影的PNG图作为背景。扁平化布局这是最根本的方法。用ConstraintLayout替代多层嵌套的LinearLayout和RelativeLayout。目标是让视图树尽可能浅。一个简单的衡量标准使用布局检查器查看你的页面视图层级深度。对于列表项RecyclerView的Item要尤其严格最好控制在3-4层以内。include和merge的绩效考量正确使用它们可以减少重复的XML代码但include本身也会增加一层视图除非根是merge。要权衡复用性和层级深度。对于非常简单的、只出现一两次的布局片段直接写可能更高效。4.2 测量与布局的性能陷阱视图的绘制过程分为三步测量Measure、布局Layout、绘制Draw。其中“测量”和“布局”发生在主线程复杂的计算会直接导致界面掉帧。wrap_content与match_parent的代价wrap_content视图需要先测量所有子内容的大小才能确定自己的尺寸。如果这个视图在一个嵌套很深的叶子节点还好但如果是一个外层容器比如根布局设置了wrap_content它可能会触发整个视图树的多次测量Measure Pass代价高昂。match_parent视图直接使用父容器给出的尺寸通常更高效。ConstraintLayout中的0dpmatch_constraint行为类似。优化建议在ScrollView或RecyclerView的Item布局中避免在最外层使用wrap_content尽量给出确定值或使用match_parent/0dp。对于固定尺寸的图片使用android:src并指定android:layout_width和android:layout_height为具体dp值而不是wrap_content可以避免ImageView额外的测量开销。4.3 多屏幕适配的核心策略Android设备碎片化严重屏幕尺寸和密度千差万别。适配的目标是让布局在不同设备上都能合理显示。1. 使用密度无关像素dp和缩放无关像素spdp用于尺寸。在160dpi的屏幕上1dp 1px。系统会根据实际屏幕密度自动缩放。sp用于字体大小。同样会随系统字体大小设置缩放。永远不要用px像素来定义尺寸或字体。2. 利用ConstraintLayout的灵活性百分比与比例使用layout_constraintWidth_percent或DimensionRatio来实现按比例伸缩的布局。屏障Barrier处理动态内容如不同语言文本长度不同导致的布局错位问题。引导线Guideline可以按百分比或固定dp值在布局中创建一条参考线将视图约束到这条线上轻松实现按比例分割屏幕。3. 提供备用布局资源Android允许你为不同的屏幕配置提供不同的布局文件。这是通过资源限定符实现的。创建layout-land文件夹在里面放置横屏版本的activity_main.xml。创建layout-sw600dp文件夹为最小宽度shortest width大于600dp的设备通常是7寸平板提供不同的布局。创建layout-w1240dp文件夹为可用宽度大于1240dp的设备如横屏的平板提供布局。系统会根据当前设备的配置自动选择最匹配的布局文件。策略是先设计一个良好的默认布局放在layout文件夹然后为差异巨大的情况提供备用布局而不是为每一种可能都做一套。4. 使用尺寸资源dimens.xml不要将尺寸值硬编码在布局XML中。在res/values/dimens.xml里定义dimen namepadding_medium16dp/dimen dimen nametext_size_large18sp/dimen然后在布局中引用android:paddingdimen/padding_medium。 你还可以创建values-sw600dp/dimens.xml为平板定义更大的尺寸值实现一套布局文件多套尺寸配置。4.4 处理键盘弹出与异形屏键盘弹出当软键盘弹出时默认会压缩窗口高度可能导致底部输入框被遮挡。解决方案在AndroidManifest.xml中对应的activity标签内设置android:windowSoftInputModeadjustResize。这样Activity主窗口会被调整大小为软键盘腾出空间。adjustPan是另一种方式它通过平移窗口内容来保证输入框可见但可能会遮挡顶部内容需根据情况选择。异形屏刘海屏、挖孔屏确保内容不被遮挡从Android 9API 28开始默认情况下系统会通过将状态栏区域变黑来防止内容延伸到刘海区域。但如果你需要全屏显示如游戏、视频就需要处理。使用窗口镶边Window Insets通过ViewCompat.setOnApplyWindowInsetsListener来监听系统窗口镶边状态栏、导航栏、刘海区域并相应地调整你的布局边距Padding确保关键内容显示在安全区域内。ConstraintLayout可以很方便地将视图约束到guideline或父容器的systemUi边上。5. 从布局到交互数据绑定与视图绑定初探当布局变得复杂在Activity或Fragment里用findViewById来获取每一个视图的引用会变得异常繁琐和容易出错。更现代的做法是使用视图绑定View Binding或数据绑定Data Binding。5.1 视图绑定View Binding安全高效的替代方案视图绑定会为每个XML布局文件生成一个绑定类。这个类的实例包含了该布局中所有具有ID的视图的直接引用。启用与使用在模块级的build.gradle中确保开启android { ... buildFeatures { viewBinding true } }在Activity中使用class MainActivity : AppCompatActivity() { // 绑定类命名规则XML文件名转驼峰 “Binding” private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 替换 setContentView(R.layout.activity_main) binding ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) // 直接通过binding对象访问视图类型安全 binding.textView.text Hello View Binding binding.button.setOnClickListener { ... } } }优势空安全只会为XML中实际存在的ID生成引用避免了findViewById可能返回null的风险。类型安全视图已经是正确的类型如TextView无需强制转换。编译更快相比数据绑定视图绑定不处理表达式或布局变量生成代码更简单编译速度更快。5.2 数据绑定Data Binding将布局与数据模型连接数据绑定更进了一步它允许你在XML布局中直接使用表达式类似简单的代码将UI组件与数据源如ViewModel绑定。启用与基础使用在模块级build.gradle中开启android { ... buildFeatures { dataBinding true } }将布局文件根标签改为layout!-- activity_main.xml -- layout xmlns:androidhttp://schemas.android.com/apk/res/android data !-- 定义变量 -- variable nameuser typecom.example.User / /data ConstraintLayout ... TextView android:text{user.name} !-- 使用表达式绑定数据 -- ... / /ConstraintLayout /layout在Activity中class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding DataBindingUtil.setContentView(this, R.layout.activity_main) binding.user User(John Doe) // 设置数据UI自动更新 } }进阶特性绑定适配器Binding Adapters自定义如何将数据设置到视图上。例如你可以创建一个BindingAdapter(imageUrl)方法实现用Glide或Picasso加载网络图片。双向绑定使用{}语法不仅数据变化更新UIUI变化如EditText输入也能自动更新数据模型。常用于MVVM架构。如何选择只需要安全地访问视图没有复杂的数据-UI同步需求用视图绑定。它更轻量编译更快。需要将布局与数据模型如ViewModel动态绑定或在XML中使用表达式逻辑用数据绑定。它是实现MVVM模式的重要工具。我个人在大多数情况下会优先使用视图绑定因为它解决了findViewById的主要痛点且足够简单。只有在确实需要数据绑定提供的动态更新和表达式能力时才会引入数据绑定毕竟它会增加编译时间和复杂度。6. 常见疑难杂症与实战排坑记录理论说再多不如真刀真枪踩几个坑。下面是我在多年开发中积累的一些典型布局问题及其解决方案希望能帮你少走弯路。6.1 文本省略号Ellipsis不显示问题你给TextView设置了android:maxLines1和android:ellipsizeend但长文本并没有显示“...”而是被截断了或者换行了。根因分析省略号生效需要几个条件同时满足TextView的宽度是受限制的match_parent、固定值或0dp约束。文本内容超出了TextView的可用宽度。对于单行省略不能设置android:inputType特别是可编辑的类型因为这会改变TextView的内部行为。解决方案检查TextView的layout_width是否足够小。如果设为wrap_content它会尝试显示全部文本省略号永远不会出现。确保没有设置android:inputType。如果TextView需要作为EditText使用但又想省略这是一个矛盾的需求可能需要自定义View或改变设计。对于多行省略maxLines 1同样需要确保宽度受限并且总文本高度超过maxLines允许的高度。6.2 ScrollView与ListView/RecyclerView的嵌套冲突这是一个经典陷阱。ScrollView自己可以滚动ListView/RecyclerView自己也可以滚动。把它们嵌套在一起滚动冲突会导致内部列表无法正确测量高度通常表现为只显示第一项或几项。解决方案最佳方案避免嵌套。重新设计布局看是否能用RecyclerView的多类型ItemItemType来统一实现所有内容或者使用NestedScrollView它是ScrollView的增强版能更好地处理嵌套滚动配合LinearLayout来替代内部的列表。如果必须嵌套极少数情况对于ListView可以重写其onMeasure方法有风险且已过时。对于RecyclerView可以设置android:nestedScrollingEnabledfalse来禁用其自身的滚动让它将所有Item一次性展开由外层的ScrollView或NestedScrollView来负责滚动。但这会严重破坏RecyclerView的视图复用机制导致性能急剧下降只适用于Item数量极少的情况。6.3 图片变形与缩放类型ImageView显示图片时如何保持宽高比不拉伸变形关键在于android:scaleType属性。fitXY拉伸填满整个View会变形。不推荐。fitCenter默认值。保持宽高比缩放图片使得整张图片完整显示在View中可能上下或左右留空。centerCrop保持宽高比缩放图片使得图片的短边填满View长边超出部分被裁剪。这是做全屏背景或头像裁切的常用选项。centerInside保持宽高比缩放图片使得整张图片完整显示在View中与fitCenter类似但不会放大图片如果图片比View小就居中显示。保持固定宽高比的技巧对于ConstraintLayout可以设置app:layout_constraintDimensionRatioH,16:9表示宽高比16:9H指以高度为基准计算宽度。同时将宽度或高度至少一个设为0dpmatch_constraint。6.4 动态改变布局参数有时需要在代码中动态调整视图的位置或大小。val params myView.layoutParams as ConstraintLayout.LayoutParams // 修改约束 params.topToBottom R.id.other_view // 修改边距注意是setMargins单位是px通常用dp转换 params.setMargins(dpToPx(16), 0, 0, 0) // 修改宽度 params.width ConstraintLayout.LayoutParams.MATCH_PARENT // 应用更改 myView.layoutParams params // 有时需要请求重新布局 myView.requestLayout()关键点获取到的LayoutParams类型必须与父容器的类型匹配ConstraintLayout对应ConstraintLayout.LayoutParams。修改参数后需要将新的params对象重新设置给视图。修改了影响尺寸或位置的参数后通常需要调用requestLayout()来触发一次新的测量和布局流程。6.5 处理“看不见”的视图Visibility的坑视图有三种可见性状态VISIBLE可见、INVISIBLE不可见但占位、GONE不可见且不占位。将视图设为GONE后它在布局中占据的空间会被释放周围的视图会重新排列。这在ConstraintLayout中通过约束的“Gone Margin”特性可以很好地处理。但要注意频繁切换VISIBLE和GONE尤其是在列表或动画中会触发频繁的重新布局requestLayout可能影响性能。对于需要频繁显示/隐藏的视图可以考虑通过修改透明度alpha或平移translation来实现而不是改变visibility。最后关于布局的学习我的体会是它是一门实践性极强的技能。不要只看不动手最好的方法就是在Android Studio里新建一个项目把每种布局管理器都拖进去试试改改参数看看预览效果再运行到模拟器或真机上观察。遇到问题就按我们上面说的调试方法一步步排查。把那些常见的错误都亲手犯一遍印象才会深刻。当你能够不假思索地根据UI设计稿在脑子里构建出高效的布局结构并快速用代码实现时你就真正跨过了Android界面开发的第一道大门。