Android的xml文件中的theme和style属性的区别与联系;style、declare-styleable、attr这三个标签的区别与联系

xml文件中的theme和style属性的区别与联系

注意:这里讲的theme和style是xml中某个标签(如application标签)中的属性,而不是标签,后面要讲的style标签其实是属性值(即style属性的值)。总之,前者是属性后者(即标签)是属性值。

theme属性和style属性

<application android:theme="@style/CustomTheme">

<TextView android:style="@style/myStyle" />

style标签

<style/>

区别

  1. 作用范围不同
    对于Android开发者来说Theme主要是针对窗体及Activity级别的,通常改变的是窗体的样式;而Style主要是针对窗体及Activity中具体成员元素级别的,通常改变的是控件的样式。简单粗暴理解就是Theme作用于所有(若在Theme 中单独为background 这一属性赋值,则对所有View的background都起作用,ViewGroup和它的子成员的背景会重叠)支持属性的子成员,Style作用于指定的成员。

  2. 赋值方式不同
    theme的赋值方式:
    系统为theme这一属性提供了多个属性值(都含有Theme),比如Theme.Light 。
    使用系统自带主题赋值的方式:@android:style/
    使用自定义主题赋值的方式:@style/

<!-- 使用系统预制style -->
<activity android:theme="@android:style/Theme.Dialog">

<!-- 使用系统预制但局部修改的style -->
<activity android:theme="@style/CustomTheme">
<color name="custom_theme_color">#b0b0ff</color>
<style name="CustomTheme" parent="android:Theme.Light">
    <item name="android:windowBackground">@color/custom_theme_color</item>
    <item name="android:colorBackground">@color/custom_theme_color</item>
</style>

style属性的赋值方式:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:style="@style/myStyle" />

联系

实际上,theme实质上是style,因为theme和style属性的值都通过style 标签定义得到的。
参考:Android开发之Theme、Style探索及源码浅析


style、declare-styleable、attr这三个标签的区别与联系

注意:这三个标签分别对应R类中的R.style、R.styleable、R.attr这三个内部类。

区别

  • attr
    attr标签用于定义属性。attr不依赖于declare-styleable,declare-styleable只是为了方便attr的使用。
    我们自己定义属性完全可以不放到declare-styleable里面,比如直接在resources文件中定义一些属性:
<attr name="custom_attr1" format="string" />
<attr name="custom_attr2" format="string" />

  • declare-styleable
    declare-styleable标签用于把相关的属性组织起来,有一个分组的概念。

作用:
1、属性的使用范围更加明确(比如declare-styleable标签定义的TextViewStyle,开发者通过字面意思可知其中的属性用于更改TextView样式的,因此当我们想要知道Theme具体有哪些属性可以有效使用时,可以查阅API的R.styleable进行选择,也可查SDK中android自带的attrs.xml中的declare-styleable标签)。

2、便于在创建View时获取xml或主题等中设置的属性值

<declare-styleable name="custom_attrs">   
          <attr name="custom_attr1" format="string" />
          <attr name="custom_attr2" format="string" />
</declare-styleable>

创建View时获取属性值的方式:

TypedArray typedArray = context.obtainStyledAttributes(set,R.styleable.custom_attrs);

若是定义的属性不放到declare-styleable标签中,则在创建View时获取属性值的方式:

int[] v = {R.attr.custom_attr1, R.attr.custom_attr2};
TypedArray typedArray = context.obtainStyledAttributes(set,v);

  • style
    为一组attr属性赋值

联系

自定义View 时,获取属性值是通过obtainStyledAttributes 函数。例子:

//自定义View
 TypedArray typedArray = context.obtainStyledAttributes(set,R.styleable.custom_attrs);
//ImageView 
public ImageView(Context context, AttributeSet attrs) {  
  TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ImageView, 0, 0);
  Drawable src = ta.getDrawable(R.styleable.ImageView_src);
  setImageDrawable(src);
  ta.recycle();
}

函数的声明:

  • obtainAttributes(AttributeSet set, int[] attrs)
    从layout设置的属性集中获取attrs中的属性,若还有属性的值未获取到还会从主题中获取。
  • obtainStyledAttributes(int[] attrs)
    从主题中获取attrs中的属性。
  • obtainStyledAttributes(int resId,int[] attrs)
    从资源文件定义的style中读取属性,若还有属性的值未获取到还会从主题中获取。
  • obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
    数据来源:set、defStyleAttr、NULL(即主题中直接指定的属性值,也就是主题中单一的某个attr 属性的值)、defStyleRes。

参数介绍:

  1. AttributeSet set(数据源):即XML中的属性,表示从layout文件中直接为这个View添加的属性的集合(一种是直接使用android:layout_width=“wrap_content"这种直接指定,还有一种是通过style=”@style/somestyle"指定。)
  2. int[] attrs(目标数据的id):即想要哪个属性的值。每个元素代表一个属性在R.attr 中的id。
  3. int defStyleAttr(数据源):可配置样式。主题中配置的样式。
    例子:
<resources>  
  <style name="Theme">
 
    <!-- ...snip... -->
 
    <item name="textViewStyle">@style/Widget.TextView</item>
 
    <!-- ...etc... -->
 
  </style>
</resource>

textViewStyle 就是可配置样式,该样式只有在 obtainStyledAttributes 函数中为形参 defStyleAttr 设置了 “com.android.internal.R.attr.textViewStyle” 时, @style/Widget.TextView 中设置的属性值才会起作用。

  1. int defStyleRes(数据源):defStyleRes就要比defStyleAttr简单多了。它只是一个style资源(@style/Widget.TextView)。不需要间接的通过theme。只有当 defStyleAttr 没有定义时(设置为0,或者没有在主题中设置),defStyleRes 才有效。

,如果一个属性在多个地方都被定义了,那么以哪个为准?
优先级如下:
set 中直接指定的值 > set 中的style 资源(如:style=@style/blah)> defStyleAttr > defStyleRes > NULL(主题中直接指定的值,不包括可配置样式)
注:无论用哪个obtainAttributes 函数,当找不到属性值时,会从主题中直接指定值的属性找。 主题中的可配置样式必须在obtainStyledAttributes 函数中传入该样式在R类中的id 即defStyleAttr 才会起作用。

参考:深入理解Android 自定义attr Style styleable以及其应用


修改主题中的可配置样式

自定义主题时,继承了android 提供的主题后,修改单个属性一般是针对window 的属性,因为只作用于window,其他属性一般不要单独设置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值