在Android layout文件中,属性引用资源一般使用@,例如
android:textColor="@color/white"
但在一些系统文件中我们也可以看到有这样的写法
android:textColor="?android:color/textColor"
我们知道@是引用已经定义好的资源,如@color/white、@android:color/white,那 ‘?’ 呢?下面是文档中的解释
Referencing style attributes
A style attribute resource allows you to reference the value of an attribute in the currently-applied theme. Referencing a style attribute allows you to customize the look of UI elements by styling them to match standard variations supplied by the current theme, instead of supplying a hard-coded value. Referencing a style attribute essentially says, “use the style that is defined by this attribute, in the current theme.”
To reference a style attribute, the name syntax is almost identical to the normal resource format, but instead of the at-symbol (@), use a question-mark (?), and the resource type portion is optional. For instance:
?[:][/]
For example, here’s how you can reference an attribute to set the text color to match the “primary” text color of the system theme:
<EditText id="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:text="@string/hello_world" />
也就是说 ‘?’ 用来引用主题中的资源值,以显示当前主题的风格类型。
一般设置主题有几个方法,
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
...
application>
<activity
android:name=".MainActivity"
android:theme="@style/AppTheme"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.AppTheme);
setContentView(R.layout.activity_main);
}
例子:
主题style/AppTheme
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
-- Customize your theme here. -->
style>
主题style/AppTheme.Another
<style name="AppTheme.Another" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:background">#ffff8800item>
style>
可以看到主题将所有view的background都设置为#ffff8800
。原因是android:background
是View的一个通用属性,如果View自身没有再去设定这个值的话,就会使用当前主题下的值。
如果我们只想改变某一个view的背景颜色怎么办?这里就可以使用?
这个符号。首先在attrs.xml
中定义一个标签
<resources>
<attr name="customBackground" format="color|reference">attr>
resources>
在主题中设置这个标签的值
<style name="AppTheme.Another" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="customBackground">#ffff8800item>
style>
在布局中引用这个主题值
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
>
<TextView
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="?attr/customBackground"
android:textSize="30sp"/>
RelativeLayout>
结果如下
如果我们再定义一些其他主题,如:
<style name="AppTheme.Third" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="customBackground">#ff0099ccitem>
style>
那么只需要设置相应的主题就可以改变view的属性值。
还可以再主题里设置更多的标签,这样就可以完成像夜间主题这种背景、字体颜色等一系列属性同时改变。