最近在学习的过程中遇到了自定义的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布局,不需要更改。下面我们直接运行效果,如下:

小结:

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

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

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

手把手教你自定义attr的更多相关文章

  1. android 手把手教您自定义ViewGroup(一)

    1.概述 在写代码之前,我必须得问几个问题: 1.ViewGroup的职责是啥? ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属 ...

  2. 《手把手教你》系列技巧篇(七十一)-java+ selenium自动化测试-自定义类解决元素同步问题(详解教程)

    1.简介 前面宏哥介绍了几种关于时间等待的方法,也提到了,在实际自动化测试脚本开发过程,百分之90的报错是和元素因为时间不同步而发生报错.本文介绍如何新建一个自定义的类库来解决这个元素同步问题.这样, ...

  3. 《手把手教你》系列基础篇(八十五)-java+ selenium自动化测试-框架设计基础-TestNG自定义日志-下篇(详解教程)

    1.简介 TestNG为日志记录和报告提供的不同选项.现在,宏哥讲解分享如何开始使用它们.首先,我们将编写一个示例程序,在该程序中我们将使用 ITestListener方法进行日志记录. 2.Test ...

  4. 《手把手教你》系列基础篇(九十五)-java+ selenium自动化测试-框架之设计篇-java实现自定义日志输出(详解教程)

    1.简介 前面宏哥一连几篇介绍如何通过开源jar包Log4j.jar.log4j2.jar和logback实现日志文件输出,Log4j和logback确实很强大,能生成三种日志文件,一种是保存到磁盘的 ...

  5. 手把手教你做个人 app

    我们都知道,开发一个app很大程度依赖服务端:服务端提供接口数据,然后我们展示:另外,开发一个app,还需要美工协助切图.没了接口,没了美工,app似乎只能做成单机版或工具类app,真的是这样的吗?先 ...

  6. 手把手教你写Sublime中的Snippet

    手把手教你写Sublime中的Snippet Sublime Text号称最性感的编辑器, 并且越来越多人使用, 美观, 高效 关于如何使用Sublime text可以参考我的另一篇文章, 相信你会喜 ...

  7. 【转】手把手教你把Vim改装成一个IDE编程环境(图文)

    手把手教你把Vim改装成一个IDE编程环境(图文) By: 吴垠 Date: 2007-09-07 Version: 0.5 Email: lazy.fox.wu#gmail.com Homepage ...

  8. 手把手教你用动软.NET代码生成器实例教程

    动软实战攻略 手把手教你用动软 文档编号:20110421 版权所有 © 2004-2011 动软 在线帮助:http://help.maticsoft.com 目录   一.        产品介绍 ...

  9. 沉淀,再出发——手把手教你使用VirtualBox搭建含有三个虚拟节点的Hadoop集群

    手把手教你使用VirtualBox搭建含有三个虚拟节点的Hadoop集群 一.准备,再出发 在项目启动之前,让我们看一下前面所做的工作.首先我们掌握了一些Linux的基本命令和重要的文件,其次我们学会 ...

随机推荐

  1. ExtJs6编译之后上线报错无法查看到的解决方法

    最近Extjs编译后部署遇到了一个错误c is not a constructor,报错位置在app.js里,这根本没法找 解决方法:用命令sencha app build testing 编译之后, ...

  2. shell里面的#!

    放在第一行的#! /system/bin/sh 我之前误以为是给读代码的人看的,其实不是!!是给操作系统看的,在android添加系统(服务.应用)里面的1.1中,就是因为没有添加,导致系统运行不了t ...

  3. 深入理解JavaScript系列(38):设计模式之职责链模式

    介绍 职责链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象 ...

  4. Shiro - web应用

    先不谈Spring,首先试着用最简易的方式将Shiro集成到web应用. 即使用一些Servlet ContextListener.Filter.ini这些简单的配置完成与web应用的集成. web. ...

  5. visual studio 安装与sqlserver 安装

    先sqlserver再visual studio ,避免安装目录重复(sqlserver 中包含一部分visual  而  visual studio 中也包含有部分sqlserver内容) 安装vi ...

  6. Spring事务不起作用原因

    首先声明: Checked异常继承java.lang.Exception类.Unchecked异常继承自java.lang.RuntimeException类. 而,Spring的事务实现采用基于AO ...

  7. css-布局的漂浮

    float ** 属性值 left: 文本流向对象的右边 right:文本流向对象的左边 <html> <head> <title>World</title& ...

  8. java.util.concurrent.CyclicBarrier 使用

    1.概述 java.util.concurrent.CyclicBarrier(循环的栅栏), 构造时设置一个计数器数(count), 各线程通过调用barrier.await()进入等待,并且计数+ ...

  9. javascript实现SHA1算法

    web里面密码直接传到后台是不安全的,有时候需要进行加密,找到一个不错的javascript SHA1算法: <!DOCTYPE html> <html lang="en& ...

  10. 中国gis100强

    广州南方测绘仪器有限公司 北京四维图新科技股份有限公司 北京北斗星通导航技术股份有限公司 高德软件有限公司 北京合众思壮科技股份有限公司 中国地图出版社 广州中海达卫星导航技术股份有限公司 正元地理信 ...