Android中View自定义XML属性详解以及R.attr与R.styleable的区别
为View添加自定义XML属性
Android中的各种Widget都提供了很多XML属性,我们可以利用这些XML属性在layout文件中为Widget的属性赋值。
如下所示:
我们可以通过TextView所提供的XML属性android:text
为TextView的文本赋值。
我们在自定义View的时候也会经常需要自定义View的XML属性。
假设我们有一个自定义的View,其类名是com.ispring.attr.MyView,其中com.ispring.attr是应用程序的包名。
要想自定义XML属性,总的来说包括三步:
在xml资源文件中定义各种attr
,指定attr
的数据类型。 在自定义View的构造函数中解析这些从XML中定义的属性值,将其存放到View对应的成员变量中。 在layout文件中为自定义View的XML属性赋值。
首先,我们在res/values目录下新建了一个名为attrs_my_views.xml文件,文件名是什么不重要,只要是xml文件就行。我们在该文件中定义MyView所支持的XML属性。该文件的根结点是
,我们在
节点下可以添加多个节点,在
节点中通过
name
指定XML属性名称,通过format
指定XML属性值的类型,如下图所示:
由上图我们可知,format支持的类型有enum、boolean、color、dimension、flag、float、fraction、integer、reference、string。
当我们指定了XML属性的名称和属性值的类型之后,我们就可以在layout文件中通过XML属性为其赋值了。如下图所示:
我们通过 这样attr的属性值只能取man或woman了。 flag 在 MyView直接继承自View,我想让MyView可以显示文本,即我传递文本给MyView,MyView能画出来,就相当于非常简单的TextView。 因此,我的attrs_my_view.xml如下所示: 我们定义了两个XML属性,customText是一个string类型,表示MyView要显示的文本,customColor是color类型,表示文本的颜色。 对项目进行编译之后会生成R.java文件,R.java文件对应着R类。如果是Android Studio项目,那么R文件的目录是app\build\generated\source\r\debug\com\ispring\attr\R.java,在该文件中有内部类 在使用MyView时,我们可以在layout文件中为MyView设置customText和customColor两个XML属性。layout文件如下所示: 运行效果如下所示: 可以看出在界面上显示了蓝色的“Hello World!”文本,说明MyView的自定义属性起作用了。 我们看一下MyView的具体实现,MyView的代码如下所示:
在layout中引入了MyView,为了能够使用自定义属性,我们通常要指定一个自定义的命名空间以区别于Android的命名空间xmlns:android
,我们自定义命名空间的名字可以是任意的,通常我一般用xmlns:app
。我的App的命名空间是com.ispring.attr
,如果用Eclipse开发,那么可以这样定义命名空间xmlns:app=http:/喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc2NoZW1hcy5hbmRyb2lkLmNvbS9hcGsvcmVzL2NvbS5pc3ByaW5nLmF0dHI8L2NvZGU+o6y1q8rH1NpBbmRyb2lkIFN0dWRpb9bQ1eLR+bao0uXD/MP7v9W85Lvh09DOyszioaNBbmRyb2lkIFN0dWRpb8q508NHcmFkbGW9+NDQYnVpbGSjrLb4R3JhZGxlsrvUytDt19S2qNLltcTD/MP7v9W85NLUsPzD+73hzrKjrNTaQW5kcm9pZCBTdHVkaW/W0L/J0tTV4tH5tqjS5cP8w/u/1bzkPGNvZGU+eG1sbnM6YXBwPSZxdW90O2h0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMtYXV0byZxdW90OzwvY29kZT6jrNXi0fm2qNLltcTD/MP7v9W85NfUtq/WuM/ytbHHsEFwcLXEw/zD+7/VvOShozwvcD4NCjxwPtTa1f3It7ao0uVhcHC1xMP8w/u/1bzk1q6686OsztLDx77Nv8nS1NPDPGNvZGU+YXBwOmN1c3RvbUF0dHI8L2NvZGU+zqpNeVZpZXe1xGN1c3RvbUF0dHLK9NDUuLPWtcHLoaPI57n7ztLDx72rY3VzdG9tQXR0crXEZm9ybWF0tqjS5c6qYm9vbGVhbrXEo6zEx8O0tMu0pr7N1rvE3Mzu0LR0cnVlu/LV32ZhbHNlo6zM7tC0xuTL+8Dg0M21xNa1u+GxqLTtoaM8L3A+DQo8cD7PwsPm1Nm21GF0dHK1xGZvcm1hdLXEwODQzb340NDSu8/Cy7XD96GjPC9wPg0KPHA+Ym9vbGVhbjxiciAvPg0KYm9vbGVhbrHtyr5hdHRyyseyvLb7wODQzbXE1rWjrMih1rXWu8Tcysd0cnVlu/JmYWxzZaGjPC9wPg0KPHA+c3RyaW5nPGJyIC8+DQpzdHJpbmex7cq+YXR0csrH19a3+7SuwODQzaGjPC9wPg0KPHA+aW50ZWdlcjxiciAvPg0KaW50ZWdlcrHtyr5hdHRyysfV+8r9wODQzaOsyKHWtda7xNzKx9X7yv2jrLK7xNzKx7ihtePK/aGjPC9wPg0KPHA+ZmxvYXQ8YnIgLz4NCmZsb2F0se3KvmF0dHLKx7ihtePK/cDg0M2jrMih1rXWu8Tcyse4obXjyv278tX7yv2hozwvcD4NCjxwPmZyYWN0aW9uPGJyIC8+DQpmcmFjdGlvbrHtyr5hdHRyysew2bfWyv3A4NDNo6zIoda11rvE3NLUJb3hzrKjrMD9yOczMCWhojEyMC41JbXIoaM8L3A+DQo8cD5jb2xvcjxiciAvPg0KY29sb3Kx7cq+YXR0csrH0dXJq8Dg0M2jrMD9yOcjZmYwMDAwo6zSsr/J0tTKudPD0ru49ta4z/JDb2xvcrXE18rUtKOsscjI50BhbmRyb2lkOmNvbG9yL2JhY2tncm91bmRfZGFya6OstavKx7K7xNzTwzB4ZmZmZjAwMDDV4tH5tcTWtaGjPC9wPg0KPHA+ZGltZW5zaW9uPGJyIC8+DQpkaW1lbnNpb26x7cq+YXR0csrHs9+058Dg0M2jrMD9yOfIoda1MTZweKGiMTZkcKOs0rK/ydLUyrnTw9K7uPbWuM/yPGNvZGU+PGRpbWVuPjwvZGltZW4+PC9jb2RlPsDg0M21xNfK1LSjrLHIyOc8Y29kZT5AYW5kcm9pZDpkaW1lbi9hcHBfaWNvbl9zaXplPC9jb2RlPqGjPC9wPg0KPHA+cmVmZXJlbmNlPGJyIC8+DQpyZWZlcmVuY2Wx7cq+YXR0crXE1rXWu8Tc1rjP8sSz0rvXytS0tcRJRKOswP3I58ih1rU8Y29kZT5AaWQvdGV4dFZpZXc8L2NvZGU+oaM8L3A+DQo8cD5lbnVtPGJyIC8+DQplbnVtse3KvmF0dHLKx8O2vtnA4NDNo6zU2rao0uVlbnVtwODQzbXEYXR0csqxo6y/ydLUvathdHRytcRmb3JtYXTJ6NbDzqplbnVto6zSsr/J0tSyu9PDyejWw2F0dHK1xGZvcm1hdMr00NSjrLWrysex2NDr1NphdHRyvdq148/Cw+bM7bzT0ru49rvytuC49mVudW292rXjoaPI58/Cy/nKvqO6PC9wPg0KPHByZSBjbGFzcz0="brush:java;">
<code class=" hljs cs"><attr name="customAttr">
<enum name="man" value="0">
<enum name="woman" value="1">
</enum></enum></attr></code>
flag表示attr是bit位标记,flag与enum有相似之处,定义了flag的attr,在设置值时,可以通过|
设置多个值,而且每个值都对应一个bit位,这样通过按位或操作符|
可以将多个值合成一个值,我们一般在用flag表示某个字段支持多个特性,需要注意的是,要想使用flag类型,不能在attr上设置format为flag,不要设置attr的format的属性,直接在attr节点下面添加flag节点即可。如下所示:
节点下通过定义多个
表示其支持的值,value的值一般是0或者是2的N次方(N为大于等于0的整数),对于上面的例子我们在实际设置值是可以设置单独的值,如none、bold、italic、underline,也可以通过|
设置多个值,例如app:customAttr="italic|underline"
。
<code class=" hljs xml"><resources>
<attr name="customText" format="string">
<attr name="customColor" format="color">
</attr></attr></resources></code>
public static final class attr
,在R.attr中会发现有customText
和customColor
,如下图所示:R.attr.customText
和R.attr.customColor
分别是属性customText
和customColor
的资源ID。
<code class=" hljs xml"><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E-->
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.ispring.attr.MainActivity">
<com.ispring.attr.myview android:layout_width="match_parent" android:layout_height="match_parent" app:customtext="Hello World!" app:customcolor="#FF0000FF">
</com.ispring.attr.myview></relativelayout></code>