手把手教你自定义attr

时间:2022-05-03 19:09:16

最近在学习的过程中遇到了自定义的attr和自定义的style。因此各种百度,各种博客的学习,算是有了一个系统的了解。在这里记录下自己的收获。

一、为什么要使用自定义attr以及本文定位

在android开发中,很多时候需要我们自定义view,这其中就包含了一个view的很多属性的设置。有时候会出现android本身提供的属性并不够用(比如它针对某些控件提供的text属性,color属性等),又或者我们想将android系统提供的属性集成到一起形成自己的一套属性集合。那么这个时候,就需要我们来自定义一套自己的属性,这就是自定义attr。因此自定义attr与自定义view是密切关联的。对于自定义attr更加深入的理解,在这里推荐我十分佩服的一位大神的博客文章http://blog.csdn.net/lmj623565791/article/details/45022631

但是建议你还是阅读完本文,再去点击上面的链接。因为本文将手把手带你去实现一个自定义的attr,这样子你会了解整个自定义attr流程。既然是手把手,所以本文不会涉及到原理性的东西,而且代码十分简单易懂,因为我也是初学者,所以力求将一个初学者学习的过程展现出来,当然其中的某些疑问可能对于anroid老鸟来说是十分幼稚的。不过知识就是这样子一点点一步步收获起来的。好了,废话不多说,进入正文吧。

二、你必须要了解的

首先实现一个自定义attr的流程:

(1)先有一个自定义的view(它是你所自定义attr的使用者)

(2)然后在values文件夹下建立attrs.xml文件,编写你的自定义的属性。示例代码如下:

  <?xml version="1.0" encoding="utf-8"?>
<resources> <declare-styleable name="test">
<attr name="text" format="string" />
<attr name="testAttr" format="integer" />
</declare-styleable> </resources>

(3)在xml文件中使用自定义属性,为它赋值

(4)在自定义view中使用TypedArray获取你所赋的值,并用作其他用途。

现在主要说明编写自定义属性的代码中,即上面的xml文件中,format的含义。其实format就是为自定义的属性设置一个格式。这根android给我们提供的属性是一样的道理,比如android给我们提供的text的属性格式就是string类型的,在我们为一个TextView设置text的时候可不就是写一个字符串嘛。那么上面的代码的意思就是自定义的属性text,格式是string类型,testAttr,类型是integer。下面来看一个format都可以指定为什么。如下:

format还可以指定其他的类型比如;
reference 表示引用,参考某一资源ID
string 表示字符串
color 表示颜色值
dimension 表示尺寸值
boolean 表示布尔值
integer 表示整型值
float 表示浮点值
fraction 表示百分数
enum 表示枚举值
flag 表示位运算

可能还还有其他的疑问,比如其他关键字的含义是什么,以及是怎么使用自定义attr的。甚至还有很细的说不清的疑问。如果没有实际代码的话,很难说明白这些疑问。所以跟着我来往下一步一步写一个例子出来吧,在这个过程中,相信你的疑问应该会被解开。

三、实现自定义attr,同时解答细节上的疑问

在这个例子中,我们来实现超级简单的自定义view,在屏幕上写用画笔写出一个字符串出来。纯粹是为了说明自定义attr的实现过程的。而字符串的颜色以及字符串的内容,就采用自定义属性的方式来获取。我们心中已经有了这个自定义的view的大概了,下面就开始编写自定义attr吧。

新建项目,然后在它的res/values下面新建attrs.xml文件,代码如下:

 <?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView">
<attr name="myText" format="string"/>
<attr name="myColor" format="color"/>
</declare-styleable>
</resources>

从代码中我们可以看到,自定义了两个属性,myText和myColor,类型分别为string何color。然后要说明两点:

(1)你可以将declare-styleable看成一个集合的名称,而它里面的元素就是我们自定义的属性。它可以命名为任意名称,不过一般都命名为相应的自定义的view的名称,表示是为这个view定制的属性,也方便查阅。在这里我随便命名了一个名字,为MyView。通过这个名称就可以找到我们自定义的属性。resources标签下可以有多个declare-styleable的。
(2)标签attr下的name就是自定义的属性名,可以任意命名,format为其格式类型。

你肯定还在疑问,自定义的属性都自定义好了,怎么用呢?那么我们现在就来使用它。首先将与之相关的自定义的view先建出来。新建类CustomView继承自view,代码如下:

 package com.fuly.kun;

 import android.content.Context;

 import android.view.View;

 public class CustomView extends View {

     public CustomView(Context context, AttributeSet attrs) {
super(context, attrs); } }

代码很简单,在这个自定义的view中,我们什么都没有做。这个view肯定是要显示出来的,那么我就修改activity_main.xml的代码,将其显示出来。注意这个时候,就该为CustomView设定属性了,此时就开始使用自定义的attr了。好了,快看代码吧,代码:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:fuly="http://schemas.android.com/apk/res/com.fuly.kun"
android:layout_width="match_parent"
android:layout_height="match_parent"
> <com.fuly.kun.CustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
fuly:myText="我是自定义attr"
fuly:myColor="#00ff00"/>
</RelativeLayout>

代码很简单,我们给自定义的view赋了属性值。是不是发现了什么,有些代码跟你之前用的不一样!下面我们就来详细说明一下怎么就把自定义的属性给使用进来了。如下说明:

(1)首先观察代码的第3行,这句话就是引入了我们项目中自定义的attr。是不是发现第三行和第一行的代码很像,其实你现在明白了吧,第一行其实就是因为android系统给出的属性,所以下面我们才能使用android:layout_width等。因为引入自定义attr,主要将后缀的android替换成为项目的包名即可,即替换为了Manifest.xml下的package标签下的包名。而我们将引入的自定义attr命名为了fuly,然后在使用自定义属性时就借助fuly来找到我们自定义的属性名称了。fuly这个名称可以随便指定,没有什么规则。
(2)再观察第11行和第12行的代码,跟第9行和第10行的代码是不是很像,这就是在CustomView使用自定义的属性,并为其赋值(一定要注意和其格式类型要相同)。

好了,现在要修改CustomView的代码了。获取到我们自定义的属性值,并使用它。这其实跟android获取自带的属性是一样的道理,比如我们给一个TextView的text赋了一个字符串,然后在代码中使用getText()方法就可以这个字符串,即给text所赋的属性值。好了,快看代码吧,如下:

 package com.fuly.kun;

 import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View; public class CustomView extends View { private TypedArray ta;//用来获取自定义属性的 public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取到我们自定义的属性
ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);
} protected void onDraw(Canvas canvas) { super.onDraw(canvas);
//获取到我们为自定义的属性所赋的值
String text = ta.getString(R.styleable.MyView_myText);
int color = ta.getColor(R.styleable.MyView_myColor, 003300); Paint paint = new Paint();
paint.setColor(color);
paint.setTextSize(55);
canvas.drawText(text, 100, 100, paint);
} }

代码很简单。只不过就牵涉了一个知识点,获取自定义属性的值,要使用TypedArray这个类而已。在代码的第18行,我们获取了一个TypedArray实例,而且这个实例是跟我们自定义的属性集合MyView相关联的。然后再代码的第25和26行,就可以用这个TypedArray对象获取自定义属性的值了。注意ta.getColor的第二个参数意思是如果该属性没有赋值,就返回颜色“#003300”。然后我们将获取到的文本和颜色作用到画笔和画布上即可。

好了,MainActivtity中的代码已经加载了acitivty_main.xml布局,不需要更改。下面我们直接运行效果,如下:
手把手教你自定义attr

小结:

主要是TypedArray的对象的获得,是通过Context的,如下:
 ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);

关于它的一系列方法,可以翻看API文档,这里总结没有什么意义。

好了,相信对自定义attr有了一个初步的了解了吧。以后程序开发中要比这个里复杂的多。学习进阶,不要怕难,贵在坚持!一起进步