简单图解:

图1、一个参数的 obtainStyledAttributes 函数。

obtainStyledAttributes 使用方式
图2、两个参数的 obtainStyledAttributes 函数

obtainStyledAttributes 使用方式

图3、四个参数的 obtainStyledAttributes 函数

obtainStyledAttributes 使用方式
测试代码:

<!--提取Attrs方式Demo-->

<!--项目的Theme-->
<style name="TestBaseTheme" parent="AppBaseTheme">
    <item name="TestAttr">1</item>
    <item name="TestAttr2">1</item>
    <item name="itemTestAttr">@style/ThemeStyleTestAttr</item>
</style>

<attr name="itemTestAttr" format="reference" />

<style name="ThemeStyleTestAttr">
    <item name="TestAttr2">3</item>
</style>

<style name="DefaultAttrStyle">
    <item name="TestAttr">2</item>
    <item name="TestAttr2">2</item>
</style>

<!--自定义的attr集-->
<declare-styleable name="TestAttrStyleable">
    <attr name="TestAttr" format="integer" />
    <attr name="TestAttr2" format="integer" />
</declare-styleable>
/*
关键词概述:
attrId:自定义控件时经常用到,位于attrs.xml文件,写在一个与自定义控件同名的 styleable 中作为属性定义。
   其实可以脱离 styleable 单独定义
attrIdArray:由多个 attrId 组成
   一般会在xml文件里把多个 attrId 组成一个 styleable 来使用,这个 styleable 正是 attrIdArray
   当然也可以在代码中 arrayOf(attrId) 来创建 attrIdArray
obtainStyledAttributes():通过theme、style资源,寻找 attrIdArray 中所有 attrId 对应的值(不是声明定义的名字或格式,而是给定的值)。
   重载方法有很多,但其实都是寻找 attrId 值的。
typedArray:存放多个 attrId 的值。
*/
//从theme中寻找attrIdArray的值 (这里说的 attrIdArray的值,意思是 attrIdArray 中每个 attrId 的值)
val typedArray1 = theme.obtainStyledAttributes(R.styleable.TestAttrStyleable)
//先从styleId中寻找attrIdArray的值,找不到后从theme中寻找attrIdArray的值
val typedArray2 = theme.obtainStyledAttributes(R.style.DefaultAttrStyle, R.styleable.TestAttrStyleable)
val set: AttributeSet? = null
/* 这个方法比较复杂,有4个参数,但其实也只是按优先级从不同位置寻找attrIdArray的值
1、先从set中寻找attrIdArray的值(set就是LayoutInflater解析布局创建View时传入的,View在布局中写的"layout_width"、"style" 等属性。)
2、再寻找theme中defStyleAttr指定的style,从此style中寻找attrIdArray的值(第三个参数)
   这一步不好理解,举个例子,TabLayout源码中此值写的是 attr.tabStyle ,这样写的话,运行时就会从 theme 中寻找有没有设置 tabStyle 这条属性,
   如果设置了,就会拿取 tabStyle 对应的值 style,然后再寻找这个 style 中 attrIdArray 的值
3、接着判断 if( 由 defStyleAttr 拿到了 attrIdArray 的值,即使只拿到了一些 attrId 的值 ){
            跳过 defStyleRes,直接从 theme 中寻找 attrIdArray 的值
         } else {
            从 defStyleRes 中寻找 attrIdArray 的值(第四个参数)
            从 theme 中寻找 attrIdArray 的值
         }

参考:https://www.jianshu.com/p/61b79e7f88fc
 */
val typedArray3 = theme.obtainStyledAttributes(set, R.styleable.TestAttrStyleable, R.attr.itemTestAttr, R.style.DefaultAttrStyle)
val i = typedArray3.getInteger(R.styleable.TestAttrStyleable_TestAttr, -99)
val i2 = typedArray3.getInteger(R.styleable.TestAttrStyleable_TestAttr2, -99)
ToastUtils.toast("" + i + "_" + i2)

相关文章:

  • 2021-12-13
  • 2022-02-04
  • 2022-01-18
  • 2022-02-05
  • 2021-09-28
  • 2022-12-23
  • 2022-12-23
  • 2021-09-26
猜你喜欢
  • 2022-12-23
  • 2021-09-11
  • 2021-10-12
  • 2021-07-26
  • 2022-01-07
  • 2021-08-16
  • 2021-10-21
相关资源
相似解决方案