Android 属性自定义及使用获取浅析
一、概述
相信你已经知道,Android 可使用 XML 标签语言进行界面的定义。每个标签中有一个一个的属性,这些属性有相应的属性值。例如:
<cn.neillee.composedmenu.RotatingArcMenu
android:id="@+id/ram2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/barBgColor"
app:position="left_bottom"
app:radius="150dp"/>
有两点可以注意到:
其一,在某个自定义 ViewGroup 中,有两个自定义属性
position
、radius
,与其他属性不同的是,这两个属性的命名空间为app
。其二,系统属性
background
的属性值为?attr/barBgColor
。
二、详细介绍
2.1 自定义属性
这里介绍
app:position="left_bottom"
app:radius="150dp"
的使用。
自定义属性常见于自定义的 View 中,让我们还是以概述中的代码作为例子。自定义属性及其属性值在 /values/attr.xml
中有如下定义:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="position">
<enum name="left_top" value="0"/>
<enum name="left_bottom" value="1"/>
<enum name="right_top" value="2"/>
<enum name="right_bottom" value="3"/>
</attr>
<attr name="radius" format="dimension"/>
<declare-styleable name="ComposedMenu">
<attr name="position"/>
<attr name="radius"/>
</declare-styleable>
</resources>
在该文件中,枚举了 position
有四个属性值,并为每个属性值提供了不同的 value 值作区分。而 radius
定义为 dimension
引用,表示其值须为 dimension
类型的值。类似地,还有如有其他类型,参考文章 【Android】Android自定义属性,attr format取值类型
接下来如何获取自定义属性值就成了关键。我在自定义 ViewGroup 中使用如下代码获取到用户在 layout 文件中,自定义 ViewGroup 标签下使用到的值。
private static final int LEFT_TOP = 0;
private static final int LEFT_BOTTOM = 1;
private static final int RIGHT_TOP = 2;
private static final int RIGHT_BOTTOM = 3;
protected static final int DEFAULT_RADIUS = 150;
protected static final int DEFAULT_POSITION = RIGHT_BOTTOM;
protected int mRadius;
...
public RotatingArcMenu(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ComposedMenu, defStyleAttr, 0);
int pos = a.getInt(R.styleable.ComposedMenu_position, DEFAULT_POSITION);
mRadius = (int) a.getDimension(R.styleable.ComposedMenu_radius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_RADIUS, getResources().getDisplayMetrics()));
a.recycle();// 使用完后记得回收
}
2.2 获取系统属性
这里介绍 android:background="?attr/barBgColor"
属性的定义与获取。
我之所以如此定义,是为了使得 背景色 能够随着应用的主题切换而变化,最简单的例子就是 夜间模式。
首先,我在 values/attr.xml
文件中对 barBgColor
进行定义:
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<attr name="barBgColor" format="color"/>
</resources>
其次,在 values/styles.xml
中对该属性值进行了定义:
<resources>
<style name="AppDayTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="barBgColor">@color/ZHIHUBlue</item>
</style>
<style name="AppNightTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="barBgColor">#263238</item>
</style>
</resources>
最后,我在控件的属性中对该属性值进行了使用
<cn.neillee.composedmenu.RotatingArcMenu
android:id="@+id/ram2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/barBgColor"
app:position="left_bottom"
app:radius="150dp"/>
需要说明的是,可以不再控件属性中使用自定义的属性值,可在代码中进行获取与设置。如:
TypedValue typedValue = new TypedValue();
mContext.getTheme().resolveAttribute(R.attr.barBgColor, typedValue, true);
mRotatingArcMenu.setBackgroundColor(typedValue.data);
这里使用到了 TypedValue
这个类。
2.3 关于 TypedValue
详细介绍见官网:
https://developer.android.com/reference/android/util/TypedValue.html
此处我仅对我在上一小节中的使用做简单介绍。在使用过程中,我观察到在不同主题下,TypedValue 读取到的值如下:
在 DayTheme 中,由于我定义的是 @color/ZHIHUBlue
,对color的引用即 resourceId。因此,typedValue.resourceId 有值,且直接等效于 R.color.ZHIHUBlue
,typedValue.type=TYPE_INT_COLOR_RGB8,表示 typedValue.data 有值,为8位的颜色代码值(#rrggbb)。
在 NightTheme 中,由于我定义的是 #263238
,颜色代码值。因此,TypedValue.resourceId 无值,但 typedValue.type=TYPE_INT_COLOR_RGB8,表示 typedValue.data 有值,为8位的颜色代码(#rrggbb)。
此文在我的 Github Pages 上同步发布,地址为:Android-属性自定义及使用获取浅析
Android 属性自定义及使用获取浅析的更多相关文章
- Android读取自定义View属性
Android读取自定义View属性 attrs.xml : <?xml version="1.0" encoding="utf-8"?> < ...
- Android属性allowBackup安全风险浅析
1.allowBackup安全风险描述 Android API Level 8及其以上Android系统提供了为应用程序数据的备份和恢复功能,此功能的开关决定于该应用程序中AndroidManifes ...
- Android SearchView 自定义SearchIcon和字体颜色大小
自定义SearchView的搜索图标和字体属性相对复杂一些,记下来. 一.自定义SearchIcon 1.API版本低于21:版本小于21时,要修改SearchIcon比较复杂,需要先获取到Searc ...
- Android属性动画完全解析(上),初识属性动画的基本用法
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系 ...
- Android属性动画完全解析(中)
转载:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是 ...
- Android属性动画完全解析(上)
Android属性动画完全解析(上) 转载:http://blog.csdn.net/guolin_blog/article/details/43536355 在手机上去实现一些动画效果算是件比较炫酷 ...
- Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View
一.简介: 今天是2014年最后一天啦,首先在这里,我祝福大家在新的2015年都一个个的新健康,新收入,新顺利,新如意!!! 上一偏,我介绍了用Xfermode实现自定义圆角和椭圆图片view的博文& ...
- Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法 ...
- Android属性动画之ValueAnimator的介绍
之前两篇博客,介绍的是ObjectAnimator作用与某一个控件的某一个属性.但我们的ValueAnimator它本身并不会作用与任何一个属性,它本身也不会提供任何一种动画.它简单的来说,就是一个数 ...
随机推荐
- python read文件内容的iter方式
遍历file的方式 iter(lambda: f.read(4096), "")等价与while True: data = f.read(4096) if not data: br ...
- Class.forName(String className)这个方法的作用
Class.forName(String className)这个方法的作用 解答:通过类的全名获得该类的类对象
- JavaScript如何定义数组。
JavaScript如何定义数组. 解答: var arrTest=new Array();
- SQLite 连接两个字符串
SQLite中,连接字符串不是使用+,而是使用|| 示例: SELECT 'I''M '||'Chinese.' 将输出 I'M Chinese. 特别说明:1. SELECT 'I''M '+'Ch ...
- (转)java 静态内部类
转自:http://blog.sina.com.cn/s/blog_605f5b4f0100zbps.html 参考:http://docs.oracle.com/javase/tutorial/ja ...
- Oracle10g RAC 关闭及启动
情况1: 保养数据库及操作系统,服务器,需要关闭DB(所有实例),OS 及Server . a. 首先停止Oracle10g 环境 $ lsnrctl stop (每个节点上停止监听,也可以用srvc ...
- push certificate
developer_identity.cer <= download from Applemykey.p12 <= Your private key openssl x509 -in de ...
- 直接下载jdk压缩包方式安装
分为下面5个步骤 1.官网下载JDK 2.检查是否安装jdk,解压缩,放到指定目录 3.配置环境变量 4.设置系统默认JDK 5. 测试jdk 1.官网下载JDK 地址: http://ww ...
- log4j中将SocketAppender将日志内容发送到远程服务器
1.服务端配置 1)服务端配置文件log4j-server.properties #Define a narrow log category. A category like debug will p ...
- cocos2d-X学习之主要类介绍:动作:CCAction
引用自:http://www.cnblogs.com/lhming/archive/2012/07/01/2572238.html 类继承图: 主要函数: virtual CCObject * co ...