属性

自定义属性,首先要定义出来属性,我们新建一个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-深入理解android自定义属性(AttributeSet,TypedArray)的更多相关文章

  1. android.content.res.TypedArray-深入理解android自定义属性(AttributeSet,TypedArray)

    属性 自定义属性,首先要定义出来属性,我们新建一个attrs.xml: <?xml version="1.0" encoding="utf-8"?> ...

  2. Android 深入理解Android中的自定义属性

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/45022631: 本文出自:[张鸿洋的博客] 1.引言 对于自定义属性,大家肯定 ...

  3. 深入理解Android 自定义attr Style styleable以及其应用

    相信每一位从事Android开发的猿都遇到过需要自己去自定义View的需求,如果想通过xml指定一些我们自己需要的参数,就需要自己声明一个styleable,并在里面自己定义一些attr属性,这个过程 ...

  4. android开发:Android 中自定义属性(attr.xml,TypedArray)的使用

    今天我们的教程是根据前面一节扩展进行的,如果你没有看,请点击 Android高手进阶教程(三)查看第三课,这样跟容易方便你的理解! 在xml 文件里定义控件的属性,我们已经习惯了android:att ...

  5. Android自定义属性时TypedArray的使用方法

    有时候android传统的页面布局不足以满足我们的需求,常常需要自己定义view,通常继承View,然后重写构造方法以及onDraw等函数,再 具体实现自己定义的复杂view.我们知道在给控件赋属性时 ...

  6. 深入理解Android开发中的CoordinatorLayout Behavior

    在使用Android设计支持库(Android Design Support Library)时,很难避开CoordinatorLayout:设计库中有很多视图都需要CoordinatorLayout ...

  7. 深入理解 Android 之 View 的绘制流程

    概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...

  8. android使用自己定义属性AttributeSet

    这里为了演示使用自己定义变量,字体大小改用自己定义的属性. 首先要创建变量,创建了个values/attrs.xml文件,文件名称随意,可是要在values文件夹下: <?xml version ...

  9. [置顶] xamarin android自定义标题栏(自定义属性、回调事件)

    自定义控件的基本要求 这篇文章就当是自定义控件入门,看了几篇android关于自定义控件的文章,了解了一下,android自定义控件主要有3种方式: 自绘控件:继承View类,所展示的内容在OnDra ...

随机推荐

  1. 可以这样去理解group by和聚合函数(转)

    http://www.cnblogs.com/wuguanglei/p/4229938.html 写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不 ...

  2. Caffe学习系列(13):数据可视化环境(python接口)配置

    caffe程序是由c++语言写的,本身是不带数据可视化功能的.只能借助其它的库或接口,如opencv, python或matlab.大部分人使用python接口来进行可视化,因为python出了个比较 ...

  3. [vim]vim 在win下乱码解决

    vim在win下遇到汉字乱码早就知晓,本以为通过如下设置即可解决乱码问题 set encoding=utf-8 set fileencoding=utf-8,chinese 这样设置是可以解决源码文件 ...

  4. 20145215实验五 Java网络编程及安全

    20145215实验五 Java网络编程及安全 实验内容 掌握Socket程序的编写: 掌握密码技术的使用: 设计安全传输系统. 实验步骤 本次实验我的结对编程对象是20145208蔡野,我负责编写客 ...

  5. ThreadLocal详解

    ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量. 这个玩意有什么用处,或者说为什么要有这么一个东东?先解释一下,在并发编程的时候,成员变量如果不做任何处理其实是线程不安全的,各个线 ...

  6. 新年奉献MVC+EF(CodeFirst)+Easyui医药MIS系统

    本人闲来无事就把以前用Asp.net做过的一个医药管理信息系统用mvc,ef ,easyui重新做了一下,业务逻辑简化了许多,旨在加深对mvc,ef(codefirst),easyui,AutoMap ...

  7. android最佳实践之设备兼容性

    由于不同手机的尺寸大小,屏幕分辨率可能存在差异.在开发应用的时候,你或许遇到过这些的问题: 1, 为什么图片在另外的手机上显示的时候变小了,又或是缩小了? 2, 为什么在layout中定义好的格局在另 ...

  8. IndexOf、LastIndexOf、Substring的用法

     String.IndexOf String.IndexOf 方法 (Char, Int32, Int32)报告指定字符在此实例中的第一个匹配项的索引.搜索从指定字符位置开始,并检查指定数量的字符位置 ...

  9. Beta版本冲刺计划

    1.下一阶段需要改进完善的功能 文件读取 界面 人员批量增改 数据库 ... 2.下一阶段新增的功能 人员权限分离分化. 课表导出 ... 3.需要改进的团队分工(针对之前的不足,需要加强和改进团队协 ...

  10. [转]DBA,SYSDBA,SYSOPER三者的区别

    原文地址:http://www.oracleonlinux.cn/2010/02/dba_sysdba_sysoper/ 什么是DBA?什么是SYSDBA,什么又是SYSOPER?三者究竟有何联系呢? ...