这两天整理之前的代码时,发现一个蛮有意思的小细节,项目中的style竟然存在多继承的写法。
就是一个style既存在前缀继承的写法,同时还有通过parent继承,就像这样
<style name="A.B" parent="C">
<item ...>
</style>
其实有一点懵逼的,虽然我的理性告诉我,style单继承,parent优先级比较高,但是还是觉得需要验证一下才比较放心。
验证这个继承方式比较简单,甚至不用编译代码,用AS的预览模式就可以。
我用TextView进行演示,我们先有四个style,前两个为父类,后两个为子类
<style name="Red20Text">
<item name="android:textColor">#FF0000</item>
<item name="android:textSize">20dp</item>
</style>
<style name="BlueBlodText">
<item name="android:textColor">#0000FF</item>
<item name="android:textStyle">bold</item>
</style>
<style name="Red20Text.BothText" parent="BlueBlodText">
</style>
<style name="Red20Text.GreenBothText" parent="BlueBlodText">
<item name="android:textColor">#00FF00</item>
</style>
然后写几个TextView分别使用这几个style
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="默认文字" />
<TextView
style="@style/Red20Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="20号红色" />
<TextView
style="@style/BlueBlodText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="蓝色加粗" />
<TextView
style="@style/Red20Text.BothText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="继承两个" />
<TextView
style="@style/Red20Text.GreenBothText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="继承两个并重写一个属性" />
从预览中就可以看到,使用Red20Text.BothText的TextView(第四个)继承了parent父类的加粗以及蓝色属性,但是没有继承前缀父类的任何属性,所以,同时继承两个style的时候,只有parent方式的属性得到了继承,前缀方式的属性不会被继承,此时只是作为一个名字存在。当子类父类存在相同属性时,父类属性会被子类属性覆盖掉,类似于java的继承。
结论:style为单继承,parent方式优先级高于前缀继承,同时存在时,前缀的作用只作为名字
虽然这个写法没什么问题,google官方代码也都会这么写,比如在预定义的values文件夹下面,会看到好多类似于
<style name="Theme.AppCompat.Light" parent="Base.Theme.AppCompat.Light"/>
<style name="Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light.DarkActionBar"/>
的style,但是我还是把项目里存在的这种写法全部删掉了,大概因为我懒吧,懒得每次都想到底怎么生效。
...(* ̄0 ̄)ノ
个人理解,难免有错误纰漏,欢迎指正。转载请注明出处。