闲谈Android中的@和?符号的引用区别

在 Android 项目开发中,我们经常会用 “@” 或者 “?” 符号去引用系统或者我们应用内添加的资源,这两种符号的引用有什么区别呢,“?attr/” 与 “?android:attr/” 之间又有怎样的不同呢?本文我们不妨闲聊一下。

“@” 与 “?” 符号的引用在使用时都有一个规范的格式:"@[+][package:]type:name","?[package:][type:]name"。可以看到,二者均包含引用符号、资源所属的包、资源类型和资源名称。

@ 资源引用

“@” 符号用于引用系统和我们在项目中添加的一些固有资源(drawable,string 等),或者定义的 style 样式。比如:


  1. android:text="@string/app_name" 

这里的 app_name 就是我们自己定义在项目文件 values/strings.xml 中的字符串资源。


  1. android:text="@android:string/cancel" 

而这里的 cancel 属于 Android SDK 中的系统字符串资源,所以需要添加@android: 来指明引用来源。android: 是 package: 的一个具体实例。

? 属性引用

“?” 符号用于引用当前主题中定义的一些属性值。注意,“?” 符号通过属性名字间接引用当前主题中的对应属性值,而不是属性本身。举个例子:


  1. android:divider="?android:listDivider" 

这里的 “?” 符号通过属性名 android:listDivider 间接获取当前主题赋予该属性的值。如同 @android: 一般,?android: 表示该值源自 Android SDK 系统属性。由于在当前主题中寻找对应属性名的值,所以没有指定属性类型,其实等同于:?android:attr/listDivider。

那如何引用项目中自定义的属性呢?我们在 attrs.xml 中定义一个属性,如:


  1. <declare-styleable name="CustomTextView"> 
  2.     <attr name="colorTextCustom" format="reference|color"/> 
  3. </declare-styleable> 

显然,此时我们定义的 colorTextCustom 属性是没有值的,直接引用没有任何作用。需要在主题 style 中赋值:


  1. <style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar"> 
  2.     <item name="colorTextCustom">#FF0000</item> 
  3. </style> 
  4.  
  5. <style name="AppTheme" parent="BaseTheme"> 
  6.     <item name="android:textColor">?colorTextCustom</item> 
  7. </style> 

可以看到,这里在 BaseTheme 中对 colorTextCustom 属性赋值,并在 AppTheme 中通过 “?colorTextCustom” 引用该属性值。由于是本地项目中定义的属性,所以没有添加 android: 命名空间。其实,这种做法的好处是,AppTheme 所覆盖的 View 均可通过构造函数获取当前主题中的 colorTextCustom 属性值。

R.attr & R.style

Android SDK 中定义有很多属性和主题可供使用,详见官方文档:R.attr &R.style。使用系统资源的好处就是,满足不同系统的适配需求,较为灵活。

这里举几个常用的:

style="?android:attr/borderlessButtonStyle"

Android 5.0 默认 Button 的样式自带边框阴影,可以使用这个系统样式去除该样式。当然,这是单独设置时的操作,为了方便全局控制,可以在 styles.xml 中自定义一个样式,继承一个无边框样式作为 parent:


  1. <style name="CustomBorderlessButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless"> 
  2.     <item name="android:textColor">@android:color/white</item> 
  3.     ... 
  4. </style> 

android:background="?android:attr/selectableItemBackground"

可用于设置一些 List Item、Button之类带点击效果的背景。该样式自带触摸点击效果,在 5.0 和更高版本上,更是附有 Ripple 涟漪效果,省去我们自己实现 selector 选择器的过程。当然我们也可以自己使用 <ripple> 标签定义一个 drawable 文件实现涟漪效果,只是需要注意版本限制。

android:background="?android:attr/dividerVertical"

实现分割线背景。

还有一些其他有用的系统资源,这里就不一一列举了...

作者:亦枫

来源:51CTO

时间: 2024-11-05 14:51:36

闲谈Android中的@和?符号的引用区别的相关文章

android中广播接收器和toast的区别和联系是什么

问题描述 android中广播接收器和toast的区别和联系是什么 android中广播接收器和toast的区别和联系是什么 广播接收器是一个方法还是一个类呢 解决方案 toast是悬浮的通知http://liangruijun.blog.51cto.com/3061169/638913/ BroadcastReceiver 是用来接收通知的,两者没有可比性.http://blog.csdn.net/liuhe688/article/details/6955668 往往写一个程序需要两者配合使用

Android中home键和back键区别实例分析_Android

本文实例分析了Android中home键和back键区别.分享给大家供大家参考.具体如下: back键 Android的程序无需刻意的去退出,当你一按下手机的back键的时候,系统会默认调用程序栈中最上层Activity的Destroy()方法来销毁当前Activity,当此Activity又被其它Activity启动起来的时候,会重新调用OnCreate()方法进行创建,当栈中所有Activity都弹出结束后,应用也就随之结束了.如果说程序中存在service之类的,则可以在恰当的位置监听处理

android控件-android中ArrayAdapter和SimpleCursorAdapter有神马区别

问题描述 android中ArrayAdapter和SimpleCursorAdapter有神马区别 android中ArrayAdapter和SimpleCursorAdapter有神马区别 我知道SimpleAdapter一行数据可以显示多项内容,还可以插入图片呢 解决方案 http://www.fengfly.com/plus/view-198266-1.html 参考下,网上资料挺多的

android中handler和bundle有什么区别和联系

问题描述 android中handler和bundle有什么区别和联系 android中handler和bundle有什么区别和联系 都是用来传递消息吗都是信息的载体吗 解决方案 http://www.cnblogs.com/nuistlr/archive/2012/08/31/2665107.html handler提供了回调,接收返回,bundle打包发出信息.

Android中Handler Runnable与Thread的区别详解

转自: http://www.codeceo.com/article/android-handler-runnable-thread.html Android中Handler可以异步控制Runnable,那么这样做于Android中的Thread有什么区别呢?本文将通过多个角度来讲解这个问题,读完此文,相信你会对Android中的Handler Runnable与Thread有一个非常全面的了解. 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Th

Android中的Service 与 Thread 的区别[转]

很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service 也方便多了,下面我详细的来解释一下. 1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位.可以用 Thread 来执行一些异步的操作. 2). Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的.如:onCreat

Android中View的scrollTo()和scrollBy()区别

转自:http://blog.csdn.net/manoel/article/details/39228593 首先,需要知道的是,View是可以延伸到屏幕之外的,可以想象一下ListVIew或GridView.也就是说View的尺寸可以超过屏幕的尺寸.View的大小就是onDraw()中Canvas画布的大小.Canvas可以做translate().clipRec()t等变换,可以说Canvas是无边界的.而我们在屏幕上所见到的,只是Canvas的一部分而已.可以调用View的scrollT

Android中gravity与layout_gravity的使用区别分析_Android

android:gravity:设置的是控件自身上面的内容位置 android:layout_gravity:设置控件本身相对于父控件的显示位置. 看下如下代码段 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?><!-- android:gravity设置了按钮上面的文字的显示位置,而android:layout_gravity设置了按钮在布局中的显示位置.--><LinearLayou

Android中gravity与layout_gravity的使用区别分析

android:gravity:设置的是控件自身上面的内容位置 android:layout_gravity:设置控件本身相对于父控件的显示位置. 看下如下代码段复制代码 代码如下:<?xml version="1.0" encoding="utf-8"?><!-- android:gravity设置了按钮上面的文字的显示位置,而android:layout_gravity设置了按钮在布局中的显示位置.--><LinearLayout