博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android自定义控件系列二:如何自定义属性
阅读量:4068 次
发布时间:2019-05-25

本文共 3334 字,大约阅读时间需要 11 分钟。

上一篇Android自定义控件系列一: 我们讲了如何确定控件的属性,这篇接着也是讲个必要的知识-如何自定义属性。对于一个完整的或者说真正有实用价值的控件,自定义属性是必不可少的。


如何为控件定义属性


在res/values/attrs.xml(attrs.xml如果不存在,可以创建个)中使用<declare-styleable>标签定义属性,比如我想定义个显示头像的圆形的图片控件(AvatarImageView):

01.
<?xml version="1.0" encoding="utf-8"?>
02.
<resources>  
03.
<declare-styleable name="avatarimageview">
04.
<attr name="src" format="reference" />
05.
<attr name="border" format="dimension" />
06.
<attr name="borderColor" format="reference|color" />
07.
<attr name="borderAlpha" format="integer" />
08.
</declare-styleable>
09.
</resources>

name="avatarimageview"指定这组属性的名称,一般可以写成控件名称,标识这些属性是某个控件的。<attr>定义具体的属性,如src--定义图片的来源,border--定义控件的边框大小,borderColor--边框颜色等等。format指定属性值的类型,reference是引用类型,如引用图片、引用颜色、引用文字等。dimension是dp值。integer是整形。color是颜色编码,如果颜色编码是在colors.xml中定义的,此时要用reference,如果俩种方式都支持,中间用竖线分割。


如何获得属性值

属性的定义实际上是为了构建控件的,如上例,只有通过src拿到图片才能画,只有拿到border,才知道我要画多大的边框,所以在实例化控件之前必须能够获得属性及属性值。

为此我们必须要重写View的俩个构造方法,通过AttributeSet参数获得属性值:


(  context)

Simple constructor to use when creating a view from code.

用于通过java代码实例化控件时使用


(  context,   attrs)

Constructor that is called when inflating a view from XML.

用于在布局文件中,通过xml代码创建的控件

对于第一个构造方法,完全可以通过setXXX()来注入属性,对于上面的属性定义是没有意义,我们着重说下如何获得布局文件中的属性值。

01.
public AvatarImageView(Context context, AttributeSet attrs) {
02.
super(context, attrs);
03.
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.avatarimageview);
04.
src = a.getResourceId(R.styleable.avatarimageview_src, 0);
05.
if(src != 0)
06.
bitmap = BitmapFactory.decodeResource(this.getResources(), src);
07.
 
08.
border = (int)a.getDimension(R.styleable.avatarimageview_border, dip2px(this.getContext(), 6));
09.
 
10.
borderColor = (int)a.getColor(R.styleable.avatarimageview_borderColor, 0);
11.
if(borderColor == 0)
12.
borderColor = a.getResourceId(R.styleable.avatarimageview_borderColor, 0);
13.
if(borderColor == 0)
14.
borderColor = 0x9F7A97EA;
15.
 
16.
borderAlpha = a.getInt(R.styleable.avatarimageview_borderAlpha, -1);
17.
}

通过obtainStyledAttributes()方法获得名称avatarimageview下的所有属性的集合TypedArray。通过TypedArray就可以获得具体的属性值了。如上面代码。


如何在布局文件中使用属性


01.
<?xml version="1.0" encoding="utf-8"?>
02.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03.
xmlns:my="http://schemas.android.com/apk/res/com.kanyuan.avatarimageview"
04.
android:layout_width="match_parent"
05.
android:layout_height="match_parent"
06.
android:orientation="vertical" 
07.
android:gravity="center">
08.
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical">
09.
<com.kanyuan.avatarimageview.AvatarImageView android:id="@+id/avatarImageView" my:src="@drawable/head" my:border="2dp" android:layout_width="200dp" android:layout_height="200dp"/>
10.
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="改变头像" android:onClick="changeAvatar"/>
11.
</LinearLayout>
12.
 
13.
</LinearLayout>

假如我的控件定义在了com.kanyuan.avatarimageview包下。

首先要引入命名空间:xmlns:命名空间名称="http://schemas.android.com/apk/res/app的包名",然后通过这个命名空间引用属性,如:my:src="@drawable/head"、my:border="2dp"。之后就可以在构造方法中获得属性值了。

这样就和上篇的测量尺寸的文章接上了,通过获得padding、border等属性来计算控件实际需要多大的空间。

具体关于这个头像控件的完整源码 

==========================================================================================

欢迎加入我们的技术交流群:

Android群: 66756039
JavaEE群:  361579846 

转载地址:http://erxji.baihongyu.com/

你可能感兴趣的文章
JavaScript的一些基础-数据类型
查看>>
coursesa课程 Python 3 programming 统计文件有多少单词
查看>>
coursesa课程 Python 3 programming course_2_assessment_7 多参数函数练习题
查看>>
coursesa课程 Python 3 programming course_2_assessment_8 sorted练习题
查看>>
多线程使用随机函数需要注意的一点
查看>>
getpeername,getsockname
查看>>
Visual Studio 2010:C++0x新特性
查看>>
所谓的进步和提升,就是完成认知升级
查看>>
如何用好碎片化时间,让思维更有效率?
查看>>
No.182 - LeetCode1325 - C指针的魅力
查看>>
Encoding Schemes
查看>>
带WiringPi库的交叉笔译如何处理二之软链接概念
查看>>
Java8 HashMap集合解析
查看>>
自定义 select 下拉框 多选插件
查看>>
gdb 调试core dump
查看>>
gdb debug tips
查看>>
linux和windows内存布局验证
查看>>
本地服务方式搭建etcd集群
查看>>
安装k8s Master高可用集群
查看>>
忽略图片透明区域的事件(Flex)
查看>>