android.content.res.TypedArray-深入理解android自定义属性(AttributeSet,TypedArray)
属性
自定义属性,首先要定义出来属性,我们新建一个attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="textSize0" format="dimension" />
<declare-styleable name="button1">
<attr name="textSize1" format="dimension" />
<attr name="textSize2" format="dimension" />
</declare-styleable>
<declare-styleable name="button2">
<attr name="textSize3" format="dimension" />
<attr name="textSize4" format="dimension" />
</declare-styleable>
</resources>
然后我们要看到产生什么效果:
在R.java文件里
public final class R {
public static final class attr {
public static final int textSize0=0x7f010000;
public static final int textSize1=0x7f010001;
public static final int textSize2=0x7f010002;
public static final int textSize3=0x7f010003;
public static final int textSize4=0x7f010004;
}
public static final class styleable {
public static final int[] button1 = {
0x7f010001, 0x7f010002
};
public static final int button1_textSize1 = 0;
public static final int button1_textSize2 = 1;
public static final int[] button2 = {
0x7f010003, 0x7f010004
};
public static final int button2_textSize3 = 0;
public static final int button2_textSize4 = 1;
};
}
我在这里把不相关的内容去掉了,在这里我们可以看到通过修改attrs.xml,R文件的改变是多了两个类,分别是attr类和styleable类,这里我们要注意的是区分出来这两个类,他们是不同的,后面获得TypedArray的时候他们的区别就会很明显。在我理解,attr就是属性呗,就想定义一个变量似的定义一个属性。styleable就是样式,就是属性的集合,在R文件里体现的很明显,button1就是样式,它包含两个属性的地址,就是0x7f010001和0x7f010002。还有一个值得注意的地方时button1_textSize1这个属性,它的作用就是下标。后面我们在TypedArray里取值的时候会用到。
AttributeSet
api的解释:
A collection of attributes, as found associated with a tag in an XML document. Often you will not want to use this interface directly, instead passing it to Resources.Theme.obtainStyledAttributes() which will take care of parsing the attributes for you. In particular, the Resources API will convert resource references (attribute values such as "@string/my_label" in the original XML) to the desired type for you; if you use AttributeSet directly then you will need to manually check for resource references (with getAttributeResourceValue(int, int)) and do the resource lookup yourself if needed. Direct use of AttributeSet also prevents the application of themes and styles when retrieving attribute values.
这里只是粘了一部分过来,可以自己查看,反正AttributeSet这个类就是代表xml里一个节点下面的属性的集合,这个类一般都是系统在生成有xml配置的组件时生成,我们一般不去生成该对象。我们可以通过该对象操作xml里对应的属性,但是官方不建议这么使用,最直接的原因上面英文里有提到,就是它只是xml里属性的一个集合,没有做其他的处理,比如一个样式,这个类只是知道这个样式不能直接拿到样式里面的属性,其他原因不详,举个例子:在XML文件中定义View如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
> <com.yongdaimi.costomview.CustomTextView
android:text="China"
android:clickable="false"
style="@style/text_style"
android:textColor="@android:color/black"
/> </RelativeLayout>
然后在java代码解析当前所定义的属性值。比如:style属性。
package com.yongdaimi.costomview; import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView; public class CustomTextView extends TextView { public CustomTextView(Context context) {
this(context,null);
} public CustomTextView(Context context, AttributeSet attrs) {
this(context,attrs,0);
} public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); int attributeCount = attrs.getAttributeCount();
Log.i("test123", "当前属性个数为:"+attributeCount); for (int i = 0; i < attributeCount; i++) {
String attributeName = attrs.getAttributeName(i);
Log.i("test123",String.format("当前属性索引为:%d,索引名为:%s", i,attributeName));
if (attributeName.equals("style")) {
String attributeValue = attrs.getAttributeValue(i);
Log.i("test123", "当前属性值为::"+attributeValue); } }
} }
程序打印如下:
可以看到,通过此种形式,无法彻底读取出当前属性的值。
TypedArray
我认为这个类是学习自定义属性最重要的,首先来看它是什么:
Container for an array of values that were retrieved with Resources.Theme.obtainStyledAttributes(AttributeSet, int[], int, int) or Resources.obtainAttributes. Be sure to call recycle when done with them. The indices used to retrieve values from this structure correspond to the positions of the attributes given to obtainStyledAttributes.
它就是属性的集合,我们获取属性一般就是这个类的.getxxx()方法。
重点是学习这个类的实例是怎么来的?一般是由context.obtainStyledAttributes这个方法,有4个重载的方法。
我们来看
TypedArray android.content.Context.obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
下面分别说一下四个参数的意思:
set: XML文件中定义的View的属性的集合。举例:假设你在XML文件中定义了一个TextView并给其指定了6个属性,那么这个set里面就有6个属性。这个东西在自定义View的构造方法里面,由操作系统返回的。
attrs: 这个View自身的属性集合,是一个int数组。举例:假设你需要自定义View,并需要设置其属性,那么就需要在attrs.xml文件为其指定一个styleable。同样,在R文件中就会自动生成一个int[]数组,int[]数组中包含的就是styleable里面指定的属性。
defStyleAttr: 这是当前Theme中的一个attribute,是指向style的一个引用。如果在layout.xml和style中都没有为View指定属性时,会从Theme中这个attribute指向的style查找相应的属性值
参考链接:
1.菜鸟进阶之深入理解android自定义属性(AttributeSet,TypedArray)
2.Android中自定义样式与View的构造函数中的第三个参数defStyle的意义
android.content.res.TypedArray-深入理解android自定义属性(AttributeSet,TypedArray)的更多相关文章
- 【BUG】android.content.res.Resources$NotFoundException: File res/drawable-xxhdpi/toolbar_line.png from
SafeGod在coolpad(4.0)上执行.登陆进去的设备列表界面遇到的问题.三星和索尼没有这个问题. 06-24 15:23:06.897: E/AndroidRuntime(12655): F ...
- (转载)android:android.content.res.Resources$NotFoundException: String resource ID #..
android.content.res.Resources$NotFoundException: String resource ID #0x0 找不到资源文件ID #0x0 原因分析如下: 遇到这种 ...
- android.content.res.Resources$NotFoundException:String resource ID #ffffffff
无语,搞了半天,只能去插这个错误代号,结果就找到了这个结果. scoreTextView.setText(score+""); 这个一定要自己手动转换..不科学啊..关键是在ecl ...
- android.content.res.Resources$NotFoundException: String resource ID #0x1
之前忘了记录这个错误,今天又遇到了.唉,人不能纵容自己犯懒,遂记录之. 错误:android.content.res.Resources$NotFoundException: String resou ...
- android错误之android.content.res.Resources$NotFoundException:
错误:android.content.res.Resources$NotFoundException: String resource ID #0x1 原因:一般发生在参数 int resId 错误, ...
- 调用android的getColor()方法出现 java.lang.NoSuchMethodError: android.content.res.Resources.getColor
1.java.lang.NoSuchMethodError: android.content.res.Resources.getDrawable/getColor或者 java.lang.NoSuch ...
- Android报“android.content.res.Resources$NotFoundException: String resource ID #0x2”错误
Android报“android.content.res.Resources$NotFoundException: String resource ID #0x2”错误 当调用setText()方法时 ...
- Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f070058 android-studio 3.0 from canary 5 to canary 6
我升级android-studio到了3.0 canary 6打包编译安装出现如下错误: 07-11 13:00:39.523 8913-8913/dcpl.com.myapplication E/A ...
- 异常 android.content.res.Resources$NotFoundException: String resource ID #0x61
09-09 16:08:41.554: E/Weaver(13140):09-09 16:08:41.554: E/Weaver(13140): android.content.res.Resourc ...
随机推荐
- php之快速入门学习-13(PHP 循环 - While 循环)
PHP 循环 - While 循环 循环执行代码块指定的次数,或者当指定的条件为真时循环执行代码块. PHP 循环 在您编写代码时,您经常需要让相同的代码块一次又一次地重复运行.我们可以在代码中使用循 ...
- hadoop safemode error
http://www.cnblogs.com/hustcat/archive/2010/06/30/1768506.html 1.safemode bin/hadoop fs -put ./input ...
- 浅析android应用增量升级(转)
By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处 很久没有更新博客了,真是堕落啊,几次想提起笔,却总是被各种琐事耽搁,以后会多写文章记录点滴. 背景 ...
- System.out.print实现原理猜解
我们往往在main中直接调用System.out.print方法来打印,但是其实就这简单的一步里面有很多的玄机,因为main是static的,所以只能调用static的函数,那么print是stati ...
- HDUOJ--点球大战
点球大战 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- JS打开新窗口防止被浏览器阻止的方法[转]
本文实例讲述了JS打开新窗口防止被浏览器阻止的方法.分享给大家供大家参考.具体分析如下: 用传统的window.open()方式打开新窗口,会被浏览器阻止,那么,我们如何才能让JS打开新窗口不被浏览器 ...
- 基于SpringCloud的微服务实践
微服务不同于单一架构应用, 是典型的分布式场景, 各服务之间通过IPC进行通信. 实现微服务的过程中, 我们需要解决以下问题: 服务注册和服务发现. 根据应用选择合适的通信协议和数据协议. 例如可以选 ...
- JMeter学习笔记--详解JMeter逻辑控制器
JMeter使用逻辑控制器来决定采样器的处理顺序 简单控制器(Simple Controller):存储设备(将某些采样器归组) 循环控制器(Loop Controller:设置循环次数 仅一次控制器 ...
- zabbix中文乱码的解决办法
配置zabbix,发现中文不能正常显示,出现如下图所示的乱码: 修改方法: 1.从windows下控制面板->字体->选择一种字体例如“新宋体” 2.把它拷贝到zabbix的web端的fo ...
- AME_AME审批中子元素的概念和用途(概念)
2014-05-30 Created By BaoXinjian AME: Oracle Approvals Management AME的6个元素的概念和主要作用: Attribue -> ...