自定义属性的定义与获取,看了hyman老师的Android制作微信6.0界面,以及Android制作的QQ5.0侧滑菜单,深有感触,感觉学到了不少的东西,两个项目里面都运用到了android属性的定义与获取,所以想在博客中做下总结,方便自己以后不是很熟悉的时候来回顾一下!
以下是关于Android自定义属性的的使用步骤
1.首先定义自定义属性。
2.其次在组件中使用自定义属性,为属性赋值。
3.在java代码中获取自定义属性,并使用属性值。
以上是简单的过程,下面对过程进行详述:
1.1资源文件res中的values文件夹中自定义一个名为attrs.xml形式的文件,
其中资源文件根节点为<resources></resource>里面拥有的子节点可以为<attr> ,<declare-styleable>,
1.1.1 节点
attr节点的属性有name,format.
name就是给自定义属性命名的,最好能做到见明知意,
关于format是给自定义的属性定义一个类型,有以下的类型
-reference 引用类型 比如说自定义图片属性<attr name="icon" format="reference"></attr>
-color 颜色类型 用来自定义颜色的类型
-string 字符串类型 。。
-demension 尺寸类型 用来定义尺寸类型
-
-
1.1.2 节点
declare-styleable节点也拥有子节点<attr>
把<resource>节点内的子节点<attr>节点定义的自定义属性全部Copy到<declare-styleable>节点中,这个时候<declare-styleable>节点的子节点<attr>里面只需要name属性,自定义属性的format就可以去掉了(前提是你已经在resources节点下自定义属性节点中声明了format,当然你也可以在自定义属性的时候不声明fomat,在<declare-styleable>的子节点<attr>中来声明)。
其中你需要给<declare-styleable>节点定义一个name属性,给name属性赋值,(自定义属性多用在自定义组件,所以这里最好使用自定义组件的名字)
上面给name赋值,是为了使用自定义属性,是非常有意义的,而且是必须的。下面贴下代码加强理解
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="icon" format="reference"></attr>
<attr name="color" format="color"></attr>
<attr name="text" format="string"></attr>
<attr name="text_size" format="dimension"></attr>
<declare-styleable name="ChangeColorIconWithText">
<attr name="icon"></attr>
<attr name="color"></attr>
<attr name="text"></attr>
<attr name="text_size"></attr>
</declare-styleable>
</resources>
2.1自定义属性完成后,接下来要使用自定义属性了
首先我们来比较一下自定义属性与系统自带的属性,比如说
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
这些系统自带的属性 开头都是android: 他们的命名空间在
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
这里我们要看到的是xmlns 意思是xml name space xml命名空间 在、、apk/res/android下面
而这里我们自己使用自己的自定义属性 就必须要加入自己的命名空间,还是与自定义搭上边
自定义命名空间的方法:
xmlns:hyman="http://schemas.android.com/apk/res/com.imooc.weixin6_0"
这里的hyman名字是自己取的,当然要和你的项目有关,然后与系统的提供的属性集合一样,我们只需要把res/后面的内容换掉,把android换成自己项目的包名。一定是自己项目的包名,不是java文件所在的包名。
命名空间完毕,使用自己的自定义属性,给属性值赋值,贴代码
其实我觉得使用自定义的属性的最重要的地方就是给自定义属性赋值,我们要利用的是值,自定义属性的都是容器,容器里面装的是值
<com.imooc.weixin6_0.ChangeColorIconWithText
android:id="@+id/id_indicator_one"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:padding="5dp"
hyman:icon="@drawable/ic_menu_start_conversation"
hyman:text="@string/app_name"
hyman:text_size="12sp"
hyman:color="#ff45c01a" />
上面使用的自定义属性,使用提示的时候有时候、eclipse会给提示,有时候不会。
3.1最后一步了,是时候在java代码中使用自定义的属性了,并获取自定义属性的值去进行一系列操作
java代码中获取自定义的属性值我们就不得不说到两个重要的类的了,第一个重要的类是TypedArray,第二个重要的类是TypedValue
3.1.1 TypedValued
最近接触到这个类比较多,而且主要是它的像素单位转换功能,网上像素单位转换有不少方法,我也转了博文,下面就不在赘述,我把博文的链接贴下面了
但是其中的dip(dp)转px的问题我还是要说一下
怎么说呢,用个不是很精确的表达就是 在android中 比如下面以调语句
int viewWidth=50;
如果上面的自被应用到显示方面的问题,它的基本单位是px(自己琢磨,如果有问题请评论哈,谢谢)
device independent pixels)也就是设备独立像素。
为了达到一个app界面在不同的手机上显示合适的大小,所以要将dp转换为px ,不同的设备转换数字会不同
在三星S4中 50dp=150px
在MX3中 50dp=137px (我拿鸟哥 和我的手机测出的!)
3.1.2 TypedArray
TypedArray类这个类我也在转过博客,
主要在这里说下怎么用TypedArray来获取自定义属性在java中
首先
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ChangeColorIconWithText);
通过上下文context对象调用obtainStyleAttributes()方法来得到TyedArray 对象 (这个时候我们给<declare-styleable>节点命名终于派上用场了)
然后
int n = a.getIndexCount();
通过TypedArray对象获取一共使用了几个自定义的属性获取了自定义属性就可以调用for和switch语句了
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.ChangeColorIconWithText_icon:
BitmapDrawable drawable = (BitmapDrawable) a.getDrawable(attr);
mIconBitmap = drawable.getBitmap();
break;
case R.styleable.ChangeColorIconWithText_color:
mColor = a.getColor(attr, 0xFF45C01A);
break;
case R.styleable.ChangeColorIconWithText_text:
mText = a.getString(attr);
break;
case R.styleable.ChangeColorIconWithText_text_size:
mTextSize = (int) a.getDimension(attr, TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12,
getResources().getDisplayMetrics()));
break;
}
}
用完TypedArray后别忘了
a.recycle();
最后一点要说明的是在自定义的组件中使用自定义属性的时候,系统会默认调用3个参数的构造方法,当未使用自定义属性的时候会默认的调用2个参数的构造方法,上面的代码一般是写在3个参数的构造方法中
(hyman老师在讲QQ5.0侧滑菜单的时候是这么说的,后来更正了这个错误,就算使用自定义属性也是调用两个参数的构造方法)
public ChangeColorIconWithText(Context context, AttributeSet attrs,
int defStyleAttr)
其中利用TypedArray对象来获取索引,以上代码。。
这里贴一张更加精简的获取自定义属性的方法(朋友截图)这个方法更加的精简
通过TypedArray对象的getXxxx()方法来获取自定义属性值,getDrawable()和getColor()和getDimension()
方法都有一个默认值的参数,就是获取不到值的时候就使用默认值。
最后一个getDimension默认值的意思是将12sp转换成?px;
到这里Android自定义属性和属性值得获取就结束了。
关于这个方法我想做一个总结
- 首先Android的思想也就是把数据定义与代码的操作分开的思想就很让我觉得非常牛X了,自定义属性更加让Android代码整洁美观,方便维护与修改
- 其次自定义属性可以可以避免一些麻烦,比如说上述的关于像素单位的问题,如果在java代码中定义一个dp单位像素值,必须要使用工具方法来进行转换成px,自定义属性可以避免这个麻烦(不过在getDimension()默认值参数中要转换,这是必须的。除非你指定的就是一个px,避免不掉的麻烦)。