在android开发过程中,用到系统的View时候可以通过XML来定义一些View的属性。比如ImageView:
android:src 和android:scaleType为ImageView指定了图片源和图片缩放类型。
其实我们也可以自定义图片的这种属性。
下面以自定义标题栏为例,简单说明下自定义View属性。
比如在项目中,经常会用到标题栏,左边是返回,中间是标题,右边是下一步。如下图:
如果,每一次用到标题都在XML里面进行布局,那就太麻烦了。我们可以自定义一个标题栏。
自定义View的方式基本有三种:
1,继承View类,比如 View ImageView。
2,组合的方式,就是把已知的多个View组合在一起。也是通过继承其中一个View,用动态加载的方式,把其他View组合到一起。
3,继承ViewGroup类,比如我们熟悉的五大布局,ViewPager等。
我们使用第二种,组合的方式。
在构造函数中,动态的把标题栏的xml文件加载进去。
common_title.xml:
xml version="1.0" encoding ="utf-8" ?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width= "fill_parent" android:layout_height= "match_parent" android:layout_gravity= "center" android:background= "#123456" > <LinearLayout android:id="@+id/left_ll" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:gravity="center_vertical|left" android:orientation="horizontal" > <ImageView android:id="@+id/left_iv" android:layout_width="25dip" android:layout_height="match_parent" android:src="@drawable/back" android:layout_marginLeft="10dip" /> < TextView android:id="@+id/left_tv" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="10dip" android:gravity="center_vertical" android:textColor="#ffffff" android:text="返回" android:textSize="16sp" /> </LinearLayout> <LinearLayout android:id="@+id/right_ll" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_alignParentRight="true" android:orientation="horizontal" > <ImageView android:id="@+id/right_iv" android:layout_width="25dip" android:layout_height="match_parent" android:src="@drawable/next" android:layout_marginLeft="10dip" /> < TextView android:id="@+id/right_tv" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="10dip" android:gravity="center_vertical" android:textColor="#ffffff" android:text="下一步" android:textSize="16sp" /> </LinearLayout> <LinearLayout android:id="@+id/middle_ll" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_toLeftOf="@id/right_ll" android:layout_toRightOf="@id/left_ll" android:gravity="center_horizontal" android:orientation="horizontal" > < TextView android:id="@+id/middle_tv" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="我是标题" android:gravity="center_vertical" android:textColor="#ffffff" android:textSize="16sp" /> <ImageView android:id="@+id/middle_iv" android:layout_width="25dip" android:layout_height="match_parent" android:src="@drawable/click_down" /> </LinearLayout> </RelativeLayout>
<?
OK,现在CommmTitleView已经是有界面的View了,我们在XML中直接使用可以使用了。
图中,my: 开头的就是自定义属性,我定义了CommonTitleView的左边图片,左边文字,右边图片等。接下来就接着讲如何实现。
首先要在value文件夹下建立attr.xml:
<?xml version="1.0" encoding ="utf-8" ?> <resources> <declare-styleable name= "CommonTitleView"> < attr name= "leftTv" format ="integer" /> < attr name= "leftIv" format ="integer" /> < attr name= "rightTv" format ="integer" /> < attr name= "rightIv" format ="integer" /> < attr name= "middleTv" format ="integer" /> < attr name= "middleIv" format ="integer" /> </declare-styleable> </resources>
这个文件声明了有哪些自定义属性。其中 attr:name 是自定义属性的名称,format后面是该属性的类型。
format属性有:
reference 表示引用,参考某一资源ID
string 表示字符串
color 表示颜色值
dimension 表示尺寸值
boolean 表示布尔值
integer 表示整型值
float 表示浮点值
fraction 表示百分数
enum 表示枚举值
flag 表示位运算
attr.xml就是声明了这个View有哪些属性,属性名称是什么,属性类型是什么。
然后,在声明下命名空间,就可以使用自己定义的这些属性了。
第一行,是系统的命名空间。
第二行,xmlns:my就是我们APP自身的命名空间。声明后,就可以使用我们在attr.xml中声明的属性了。
那么,在XML中声明这些属性后,如何让CommonTitleView知道我们声明了哪些属性呢?
这就需要在CommontitleView,构造函数中,获取这些属性,然后根据获取的属性值,做出处理。如下图:
在构造函数中,我们使用TypedArray把在xml文件中声明的属性装起来。关于TypedArray的介绍,源码里面很简单:就是装属性的容器。
然后依次,通过我们在attr.xml中设置的属性名称,获取对应的值。
比如,xml中写的是my:leftIv="@drawble/back"
在构造函数中通过
int resouce_left_iv = typedArray.getResourceId ( R.styleable.CommonTitleView_leftIv, 0);
得到资源文件back图片的资源ID。
R. styleable .CommonTitleView_leftIv的意思就是名称为CommonTitleView的leftIv属性。
那么,resouce_left_iv 就是图片back对应的资源ID.
其他的属性都是通过上述方法添加进去的,比如文字等。
拿到资源ID后,就可以把资源设置到定义的View中。
这样,我们自定义的标题栏就OK了。
除此之外,还可以为标题栏中的返回,下一步等设置监听。
还可以定义接口,在外部使用的时候动态的来设定标题栏中的内容:
下面是在Activity中使用的例子:
现在main.xml中定义
在Activity中自由的设置监听:
最后附上源码:http://pan.baidu.com/s/1ntxiPTn