1. XML 解析阶段:
    • 系统解析 feed_ad_operate_download_order.xml
    • 遇到 app:layoutId=“@layout/feed_ad_operate_download_order_layout” 属性
    • 将该属性值存储在 AttributeSet
  2. View 构造阶段:
    • 创建 SimpleFeedAdInfoView 实例
    • 调用父类 SimpleAdInfoView 的构造函数
    • 构造函数中调用 init(attrs)
    • init() 方法调用 setLayoutByAttrs(attrs)
    • attrs 中读取 layoutId 属性值
    • R.layout.feed_ad_operate_download_order_layout 存储到 mLayoutId 成员变量
  3. View 渲染阶段:
    • SimpleAdInfoViewonFinishInflate() 或其他初始化方法中
    • 使用 mLayoutId 加载真正的布局文件
    • LayoutInflater.from(getContext()).inflate(mLayoutId, this, true)
    • feed_ad_operate_download_order_layout.xml 中的视图添加到 SimpleFeedAdInfoView

这就是为什么:

  • feed_ad_operate_download_order.xml 只是一个”外壳”
  • 真正的布局在 feed_ad_operate_download_order_layout.xml
  • SimpleFeedAdInfoView 通过自定义属性 app:layoutId 实现了动态加载内部布局的能力

这种设计的好处是:

  • 解耦:外壳布局与内容布局分离
  • 复用:同一个 SimpleFeedAdInfoView 可以加载不同的内部布局
  • 灵活:通过 XML 属性即可切换内部布局,无需创建多个 View 类

更新: 2025-12-10 23:46:43
原文: https://www.yuque.com/dongpozhouzi-mshe3/zhm85g/liia5dn6yukh6fp2