Android自定义属性详细剖析(一)
来源:互联网 发布:mac 浏览器 收藏夹 编辑:程序博客网 时间:2024/05/17 01:08
转载请注明出处:
http://blog.csdn.net/qq347198688/article/details/52665975
本文出自【何嘉龙的博客】
1. 引言
对于自定义属性,我相信大家都接触过,使用过。但是可能对自定义属性存有一些疑问,比如说:
为什么要用到自定义属性?
为什么在xml文件中要用到自定义的命名空间?
TintTypedArray与TypedArray有什么不同?
format有什么用?可以不加么?
让我们带着这些问题,来进行这篇博客的学习。
2. 常见的例子
进行学习的最好方式,就是有例子作为参考,而不是只是单纯给你灌输理论知识,这样只会苦涩难懂,让新手畏惧不前。
- 在value目录下新建一个attrs.xml文件如下:
- 接着在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>
- 自定义一个View类
package com.example.attrtest;import android.content.Context;import android.support.v7.widget.TintTypedArray;import android.util.AttributeSet;import android.util.Log;import android.view.View;/** * Created by dragonhaw on 2016/9/26. */public class MyTextView extends View { private static final String TAG = MyTextView.class.getSimpleName(); public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TintTypedArray typedArray = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.test, defStyleAttr, 0); String text = typedArray.getString(R.styleable.test_text); int testAttr = typedArray.getInteger(R.styleable.test_testAttr, -1); Log.e(TAG, "text = " + text + ", testAttr = " + testAttr); typedArray.recycle(); }}
- 在布局文件中使用
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.attrtest.MyTextView android:layout_width="wrap_content" android:layout_height="wrap_content" app:text="Hello World!" app:testAttr="520"/></LinearLayout>
好了,我们的自定义属性写好了,而且还放在自定义布局中使用了,那这次应该可以看到结果了吧。让我们来运行一下:
咦?好像报错了。让我们来看一下这个错误是什么?
大概意思就是, 加载我们的这个自定义View出错。我找了很久才找出解决方法,解决方法就是在自定义View里面加入这几行代码:
public MyTextView(Context context) { this(context, null); }public MyTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); }
至于出错的原因呢?我推断是当我们在自定义布局中写入我们的自定义View时,所用到的构造函数是带有两个参数的。所以,大家为了防止以后出现莫名其妙而又很难找的错误,最好把那几个构造方法都写出来。
好了,我们把错误已经找出来了,那让我们再继续运行一下:
控制台已经帮我们把结果打印出来了。再让我们看一下,那个小程序有没有把那些结果显示出来:
嗯?怎么什么都没有?哈哈,其实这才是正常的,因为你根本都没有在自定义View里面去调用onMesure(),onDraw方法,具体的请参考我转载的自定义View文章系列。咦?我们好像没有定义test_text、test_testAttr这两个item吧?但是又好像很眼熟。
其实,正如你们脑海里想的那样,代码中自定义属性名称就是这样的,”_”前面的是数组名test,后面是自定义属性名。至于declare-styleable 在Android自定义属性详细剖析(二)中剖析。
3. 解决疑问
在通过一个示例之后,再来跟大家一起解决前面提出的问题。
- 自定义属性的基本流程
我们现在attrs.xml文件中声明我们所需要的自定义属性,然后在布局文件中通过命名空间找到我们的自定义属性,接着再在布局文件中使用,然后java代码中通过obtainStyledAttributes()方法将布局文件中的自定义属性的值给传进来,进行后续操作。基本流程就是这样了。
- 为什么要使用自定义属性?
自定义属性,可以让我们直接在布局文件中,使用自己定义的属性,来完成需求。使用过开源框架的同学们应该都知道,我们在使用开源框架时,在布局文件中一般都要加上自己的自定义属性,因为这些属性系统没给我们,是我们自己定义的,来完成很多需求的。可能有同学就有疑问了,那为什么我们不直接在代码中完成需求呢?这个问题很好,其实这体现了面向对象的特性——封装性,你要用一个开源框架时,你都不需要去了解代码内部的结构,只需要在自定义布局中加入自定义属性,不是很简单么?
- 为什么在xml文件中要用到自定义的命名空间?
先让我们来看到自定义命名空间的格式,xmlns:app=”http://schemas.android.com/apk/res-auto”或者xmlns:app=”http://schemas.android.com/apk/res/com.example.attrtest”,这两个其实是一样的,但是我推荐使用第一个,IDE会自动帮你寻找到项目中的所有自定义属性。所以,要用到自定义的命名空间就是为了帮你去找你自定义的属性。
- TintTypedArray与TypedArray有什么不同?
可以看到,官方的解释是,TintTypedArray跟TypedArray提供一样的API,所以这两个随便使用哪一个都一样,不需要纠结。
- format有什么用?可以不加么?
这个是不加后的结果,直接报错。所以format是必须要加的。如果类型都不知道,我们怎么指定自定义属性的值。
format可以理解为类型, fomat的属性自己定义 根据自己的需要来选择string , integer , dimension , reference , color , enum……reference:参考指定Theme中资源ID。
dimension:尺寸值
float:浮点型
boolean:布尔值
integer:整型
string:字符串
fraction:百分数
flag:位或运算
Color:颜色
enum:枚举
好啦,自定义属性的第一部分算是讲解完了,如果感兴趣的同学,可以接着看Android自定义属性详细剖析(二)。
- Android自定义属性详细剖析(一)
- Android自定义属性详细剖析(一)
- Android自定义属性详细剖析(二)
- android 自定义控件 自定义属性详细介绍
- android 自定义控件 自定义属性详细介绍
- android 自定义控件 自定义属性详细介绍
- android 自定义控件 自定义属性详细介绍
- android 自定义控件 自定义属性详细介绍
- android 自定义控件 自定义属性详细介绍
- android 自定义控件 自定义属性详细介绍
- android 自定义控件 自定义属性 自定义Style详细介绍
- 自定义属性剖析
- Android 自定义View一(自定义属性)
- 自定义属性详细介绍
- Android 自定义控件大道(一) 自定义属性
- Android 自定义onDraw剖析
- 详细剖析asp.Net自定义404页面
- 自定义属性一
- RecyclerView上拉加载与CoordinatorLayout
- 编程练习四(并查集)
- 宽字节 转换 单字节
- equals比较与等值比较
- 第一次在这里写东西
- Android自定义属性详细剖析(一)
- ABI和ELF的全称?如何从elf文件生成bin文件?
- 小问题:linux下printf中标准输出显示问题
- String str1="abc";和String str2=new String("abc");的区别
- 2.如何把appstore里面的app图片搞出来
- android-SwipeLinearLayout解析及使用
- 143. Reorder List
- 给隐式Intent加载运行检查(Android Development Patterns S1 Ep 1)
- modbus4j ser通讯