当前位置: 首页 > news >正文

安卓基础布局核心知识点整理

一、基础布局类型

  1. LinearLayout

    • 线性排列子 View,支持垂直 / 水平方向
    • 关键属性:android:orientationlayout_weight
    <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="按钮1"/><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="2"android:text="按钮2"/>
    </LinearLayout>
    
  2. RelativeLayout

    • 通过相对位置规则放置子 View
    • 关键属性:layout_abovelayout_toRightOflayout_centerInParent
    <RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/text1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="顶部文本"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/text1"android:layout_alignParentRight="true"android:text="右侧按钮"/>
    </RelativeLayout>
    
  3. FrameLayout

    • 所有子 View 堆叠在左上角
    • 适合实现图层效果或单元素展示
    <FrameLayoutandroid:layout_width="match_parent"android:layout_height="200dp"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/image_bg"android:scaleType="centerCrop"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="图片标题"android:textColor="#FFFFFF"/>
    </FrameLayout>
    
  4. ConstraintLayout

    • 基于约束关系定位子 View,性能优化
    • 关键特性:链 (Chains)、屏障 (Barrier)、引导线 (GuideLine)
    <androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><EditTextandroid:id="@+id/input"android:layout_width="0dp"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toLeftOf="@id/button"app:layout_constraintTop_toTopOf="parent"/><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="@id/input"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
    

二、布局性能优化

  1. 减少布局层级

    • 使用 ConstraintLayout 替代嵌套 LinearLayout
    • 避免超过 3 层布局嵌套
  2. 布局复用技术

    • <include>标签:复用布局文件
    <include layout="@layout/common_toolbar"/>
    
    • <merge>标签:减少布局层级
    <merge xmlns:android="http://schemas.android.com/apk/res/android"><TextView android:layout_width="match_parent" .../><Button android:layout_width="wrap_content" .../>
    </merge>
    
  3. 延迟加载

    • ViewStub:需要时再加载布
    <ViewStubandroid:id="@+id/stub"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout="@layout/progress_view"/>
    

    java

    ViewStub stub = findViewById(R.id.stub);
    View inflated = stub.inflate(); // 延迟加载
    

三、尺寸单位

单位说明适用场景
px像素不推荐使用
dp/dip密度无关像素大多数场景
sp缩放像素文本大小
pt点 (1/72 英寸)很少使用
%百分比ConstraintLayout 中使用

四、常见面试问题

  1. LinearLayout 中 layout_weight 的工作原理

    • 剩余空间按权重比例分配
    • 建议将 width/height 设为 0dp 优化性能
  2. RelativeLayout 与 LinearLayout 性能对比

    • RelativeLayout:单次测量,但布局算法复杂
    • LinearLayout:可能需要多次测量 (有 weight 时)
    • ConstraintLayout 性能最优
  3. 如何实现流式布局 (FlowLayout)

    • 自定义 View 继承 ViewGroup
    • 重写 onMeasure 和 onLayout 方法
    • 或使用第三方库:HFlowLayout
  4. 谈谈 ConstraintLayout 的优势

    • 扁平化布局减少层级
    • 支持复杂约束关系
    • 性能优于 RelativeLayout
    • 可视化编辑器友好

五、自定义布局

  1. 继承 ViewGroup 并重写:

    • onMeasure ():测量子 View 尺寸
    • onLayout ():放置子 View 位置

    java

    public class CustomLayout extends ViewGroup {@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 测量所有子ViewmeasureChildren(widthMeasureSpec, heightMeasureSpec);// 计算自身尺寸setMeasuredDimension(width, height);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {// 放置每个子View的位置child.layout(left, top, right, bottom);}
    }
    
  2. 自定义属性:

    xml

    <declare-styleable name="CustomLayout"><attr name="item_space" format="dimension"/>
    </declare-styleable>
    

    java

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomLayout);
    int itemSpace = a.getDimensionPixelSize(R.styleable.CustomLayout_item_space, 0);
    a.recycle();
    

六、最佳实践

  1. 使用 ConstraintLayout 作为主要布局

  2. 使用 VectorDrawable 替代多分辨率图片

  3. 为不同屏幕尺寸创建布局别名

    xml

    <!-- values-sw600dp/dimens.xml -->
    <dimen name="card_padding">24dp</dimen><!-- values/dimens.xml -->
    <dimen name="card_padding">16dp</dimen>
    
  4. 使用 Data Binding 减少 findViewById

    xml

    <layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variable name="user" type="com.example.User"/></data><TextViewandroid:text="@{user.name}".../>
    </layout>
    

七、补充面试问题

1. View 的绘制流程是怎样的?
  • 核心流程measure() → layout() → draw()
    • measure:确定 View 的测量宽高(通过父容器传递的 MeasureSpec 和自身需求计算)
    • layout:确定 View 在父容器中的位置(left/top/right/bottom)
    • draw:绘制 View 的内容(背景、文本、图形等)
2. MeasureSpec 的作用是什么?
  • 定义:32 位 int 值,高 2 位表示模式,低 30 位表示尺寸
  • 三种模式
    • EXACTLY:父容器已确定精确尺寸(如match_parent或固定值)
    • AT_MOST:父容器指定最大尺寸(如wrap_content
    • UNSPECIFIED:父容器不对 View 尺寸做限制(如 ScrollView)
3. 如何优化自定义 View 的性能?
  • 关键优化点
    • 避免在onDraw()中创建对象(如 Paint 应在初始化时创建)
    • 使用setWillNotDraw(false)明确需要绘制
    • 实现onSaveInstanceState()保存状态
    • 使用Canvas.clipRect()减少重绘区域
    • 考虑硬件加速兼容性
4. FrameLayout、LinearLayout、RelativeLayout 的使用场景?
  • FrameLayout:简单堆叠场景(如加载框、图片叠加)
  • LinearLayout:单行 / 单列排列(避免过多 weight 嵌套)
  • RelativeLayout:复杂相对位置关系(已逐渐被 ConstraintLayout 替代)
5. 谈谈 ConstraintLayout 的链 (Chain) 机制
  • 作用:水平 / 垂直方向上的权重分配
  • 类型
    • Spread(默认):均匀分布元素
    • Spread Inside:两端元素贴近边界,中间均分
    • Packed:元素紧凑排列,可通过chainStyle设置权重
6. 什么情况下会导致 View 的过度绘制?如何检测和修复?
  • 过度绘制:同一像素被多次绘制(如多层重叠背景)
  • 检测工具:开发者选项 → 显示过度绘制区域
  • 修复方法
    • 移除不必要的背景
    • 使用<merge>标签减少层级
    • 按需显示隐藏视图(如使用 ViewStub)
    • 优化 Drawable 资源(避免多层 Alpha 叠加)
7. 如何实现一个自适应屏幕方向的布局?
  • 方案
    • 创建layout-landlayout-port目录存放不同方向布局
    • 使用ConstraintLayoutBarrierGuideline动态调整
    • 代码中监听屏幕旋转事件:

      java

      @Override
      public void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);// 重新布局或加载对应资源
      }
      
8. 对比match_parentwrap_content在 MeasureSpec 中的区别
属性父容器为 EXACTLY父容器为 AT_MOST
match_parentEXACTLY (父尺寸)EXACTLY (父尺寸)
wrap_contentAT_MOST (父尺寸)AT_MOST (父尺寸)
9. 自定义 View 如何支持 padding 和 margin?
  • Padding:在onDraw()中处理(如canvas.translate(paddingLeft, paddingTop)
  • Margin:需在父容器(自定义 ViewGroup)中解析 LayoutParams 并应用
10. 如何实现布局的懒加载?
  • 方案
    • 使用ViewStub(仅加载一次)
    • 动态 addView(如 Fragment 的setUserVisibleHint()
    • 配合 Jetpack 的LazyColumn/LazyRow(Compose)

八、代码实战问题

1. 手写一个正方形 ImageView

java

public class SquareImageView extends ImageView {public SquareImageView(Context context) {super(context);}public SquareImageView(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);int size = Math.min(width, height);setMeasuredDimension(size, size);}
}
2. 优化以下布局(减少层级)

xml

<!-- 原始布局 -->
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"/>
</LinearLayout><!-- 优化后(ConstraintLayout) -->
<androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/image"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintTop_toTopOf="parent"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintTop_toBottomOf="@id/image"/>
</androidx.constraintlayout.widget.ConstraintLayout>
http://www.dtcms.com/a/308161.html

相关文章:

  • 基于UDP的SNMP协议
  • Svelte 5 完全指南:从入门到跨端应用开发
  • 【Keras学习笔记】开发环境搭建
  • MATLAB 实现 SRCNN 图像超分辨率重建
  • toFixed()方法的报错注意
  • C++11原子操作实现公平自旋锁
  • 【IQA技术专题】DISTS代码讲解
  • 深入剖析:C++ 手写实现 unordered_map 与 unordered_set 全流程指南
  • Qt 如何从 .ts 文件提取所有源文
  • 2024年SEVC SCI2区,一致性虚拟领航者跟踪群集算法GDRRT*-PSO+多无人机路径规划,深度解析+性能实测
  • TDengine 中 TDgp 中添加算法模型(异常检测)
  • 【生活篇】Ubuntu22.04安装网易云客户端
  • 河南萌新联赛2025第(三)场:河南理工大学(补题)
  • .NET 10 中的新增功能系列文章3—— .NET MAUI 中的新增功能
  • gen_compile_commands.sh
  • elk部署加日志收集
  • 网络爬虫(python)入门
  • webpack-babel
  • 开发避坑短篇(11):Oracle DATE(7)到MySQL时间类型精度冲突解决方案
  • uniapp x swiper/image组件mode=“aspectFit“ 图片有的闪现后黑屏
  • Vue多请求并行处理实战指南
  • 【qiankun】基于vite的qiankun微前端框架下,子应用的静态资源无法加载的问题
  • [硬件电路-111]:滤波的分类:模拟滤波与数字滤波; 无源滤波与有源滤波;低通、带通、带阻、高通滤波;时域滤波与频域滤波;低价滤波与高阶滤波。
  • 2025做美业还有前景吗?博弈美业系统带来美业市场分析
  • rustdesk 1.4.1版本全解析:新增功能、性能优化与多平台支持详解
  • 【机器学习】KNN算法与模型评估调优
  • 深度学习批量矩阵乘法实战解析:torch.bmm
  • 【科普】在STM32中有哪些定时器?
  • 【Golang】用官方rate包构造简单IP限流器
  • 【STM32】HAL库中的实现(二):串口(USART)/看门狗(IWDG/WWDG)/定时器(TIM)