styles, attrs, them三个资源引见
styles, attrs, them三个资源介绍
这种情况下我们就可以单独定义一个style,以一种更好的做法来替代上面的写法,在此处可以把该style部分理解为"模板"。
sample1_style.xml (注:style文件必须在values-*目录中,且必须按照DTD格式来编写各个定义好的标签)
一、Styles和Themes
在Android中,style被用来指定窗体或视图的样式,比如视图的宽高、补白(padding)、背景,字体颜色等。style不需我们在代码中进行设置,
可以在xml文件中按照DTD格式进行配置。Android中的style其实跟css的思想一样,允许我们把功能实现和外观设计分离开,
View配置也提供了html中如id、name属性一样的功能标签style,让我们有能力把所有的样式集中在一个地方,
如下一个例子(main.xml)
-
<? xml version= "1.0" encoding = "utf-8"?> <LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width= "match_parent" android:layout_height= "match_parent" android:orientation= "vertical"> <TextView android:id ="@+id/tv1" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:textColor ="#FFFFFF" /> <TextView android:id ="@+id/tv2" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:textColor ="#FFFFFF" /> <TextView android:id ="@+id/tv3" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:textColor ="#FFFFFF" /> </LinearLayout>
这种情况下我们就可以单独定义一个style,以一种更好的做法来替代上面的写法,在此处可以把该style部分理解为"模板"。
sample1_style.xml (注:style文件必须在values-*目录中,且必须按照DTD格式来编写各个定义好的标签)
-
<resources xmlns:android ="http://schemas.android.com/apk/res/android">
<style name= "Sample1"> <item name= "android:layout_width">wrap_content </item> <item name= "android:layout_height">wrap_content </item> <item name= "android:textColor">#00FF00 </item > </style>
</resources>
接下来我我们对main.xml进行改造:
(注:使用时只需使用style属性引用我们定义好的style即可,这种方式可以有效的避免做重复性的工作,简化我们的工作)
-
<? xml version= "1.0" encoding = "utf-8"?> < LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width= "match_parent" android:layout_height= "match_parent" android:orientation= "vertical" > <TextView android:id ="@+id/tv1" style= "@style/Sample1" android:text ="@string/sample1_tv1" /> <TextView android:id ="@+id/tv2" style= "@style/Sample1" android:text ="@string/sample1_tv2" /> <TextView android:id ="@+id/tv3" style= "@style/Sample1" android:text ="@string/sample1_tv3" /> </ LinearLayout>
那么整个应用或整个窗体中的元素都将使用这个风格样式(如果下面的子项不存在某一属性,那么将会被忽略),
当然如果为某个特定的View指定了style时,相同的属性会被覆盖。使用 android:theme="@style/mystyle"来指定主题
-
<activityandroid:name=".Main"android:configChanges="keyboardHidden|orientation"android:screenOrientation="portrait"android:theme="@style/TitleStyle.themes"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity>
二、Style的继承
Android系统为我们提供了一整套的style,比如说显示字符串最基本的style是TextAppearance,它定义了一些最基本的属性
继承的方式有两种:(1)父Style名字.子Style名字 (2)parent="@父Style名字"
或 parent = "@style/父Style名字"
(3)继承android系统自带的style样式: parent = "@android:系统自带style的名字" 或
parent
= "@android:style/系统自带style的名字"
<style name="TitleStyle.MyStyle" parent="@android:Theme.Light">
<style
name="TitleStyle.MyStyle" parent="@android:style/Theme.Light">
注:由2与3点可以总结出,在引用其他样式(style)时,style/可以省略。
-
<style name="TextAppearance"> <item name="android:textColor">#336699</item> <item name="android:textSize">16sp</item> <item name="android:textStyle">normal</item> </style>
-
如果我们只想改变基础style中的某一项属性时,这时可以使用继承来实现
<style name= "Sample1" parent= "@TextAppearance" > < item name= "android:textColor" >#00FF00 </item > </style >
三、属性文件attrs的作用与使用
作用:attrs看字面意思就是一组属性的集合,那attrs有什么用呢,在自定义View的时候,一般会自定义一些属性,
通过构造方法中AttributeSet参数的封装,让我们能够获取到为View配置的属性。
定义attrs文件及在其他文件中引用这些属性:values/attrs.xml, values/style.xml
1、定义单个属性: <attr name="attrsName">values</attr>
eg: <attr name="myattrs">300dp</attr>
在其他资源文件中引用属性设置:?attr/属性名称
(注:?:表示引用属性,用这个标记,你所提供的资源名必须能够在主题属性中找到
a、引用系统自带的attrs。eg: ?android:attrs/系统资源ID
b、引用自定义的属性attrs。 eg: ?attrs/自定属性ID
@:下合同资源文件, eg:@string/资源ID, @android:string/资源ID)
a、在sytles.xml中使用这睦属性:
<style name="MyStyles"><item name="android:width">?attr/myattrs</item></style>b、在<TextView>标签中使用设置的属性:<TextView android:width="?attr/myattrs" />
2、定义一组属性的集合,这样的属性集合,一般都是在styles.xml或theme.xml中引用:
(1)、定义一组style属性,用<style>标签, 里面的每一项用<item>标签。(注:style属性组也可以继承)
<style name="arrayAttrs">
<item name="android:textColor">#000000</item>
<item name="android:textSize">40sp</item>
</style>
在其他资源文件中,引用这一段属性组:
a、在style.xml资源文件中引用,实质上是继承attrs.xml中的style属性组。
<style name="myStyle" parent="arrayAttrs"> </style> 或<style name="myStyle" parent="@style/arrayAttrs"> </style>b、在布局中,直接引用这些属性组attrs。<TextView style="@style/arrayAttrs" />c、在themes.xml资源文件中引用这些属性组,其方式与style.xml引用这些属性一样。<style name="myThemes" parent="arrayAttrs"></style> 或<style name="myStyle" parent="@style/arrayAttrs"> </style>3、为自定义控件设置自定义属性declare-styleable,及其使用(1)、在attrs.xml定义自定义属性。
format="color | dimension | integer ........",每一种format属性,在自定义View中都有对应的get方式来获取。format="color" ------> getColor();format="dimension" -------> getDimension();format="integer" --------> getInteger();format="reference" --------> getResourceId(); //引用类型format="boolean" ---------> getBoolean();format="float" ---------> getFloat();format="fraction" -------> getFraction(); //百分数此处还有两种类型,放在后面讲枚举和标志位。<?xml version="1.0" encoding="utf-8"?><resources xmlns:android="http://schemas.android.com/apk/res/android"><declare-styleable name="MyView"> //自定属性,此处name值一般设置为自定义控件类名字相同。<attr name="textColor" format="color"/> //定义字体颜色属性, 请注意format属性设置, getColor():方式取得该属性<attr name="textSize" format="dimension"/> //定义字体大小属性, 请注意format属性设置, getDimension():方式取得该属性<attr name="backColor" format="color" /> //定义背景颜色属性, 请注意format属性设置</declare-styleable><style name="square"> //自定义Style样式,以便其他地方引用<item name="android:layout_width">500px</item><item name="android:layout_height">300px</item></resources></style>
(2)、自定义View控件 MyView。
通过TypedArray自取自定义的declare-styleable属性组。
-
package com.fs.myselfview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Rect;import android.util.AttributeSet;import android.view.View;public class MyView extends View {private Paint myPaint;private static final String myString = "Welcome to our Zoon!";float textSize;int textColor, backColor;public MyView(Context context) {super(context);// TODO Auto-generated constructor stub}public MyView(Context context, AttributeSet attr) { //AttributeSet:自定义属性super(context, attr);myPaint = new Paint();TypedArray typeArray = context.obtainStyledAttributes(attr, R.styleable.MyView);// TypedArray是一个数组容器textSize = typeArray.getDimension(R.styleable.MyView_textSize, 30);// 防止在XML文件里没有定义,就加上了默认值30textColor = typeArray.getColor(R.styleable.MyView_textColor, 0xFFFFFF);// 同上,这里的属性是:名字_属性名backColor = typeArray.getColor(R.styleable.MyView_backColor, 0xFFFFFF); // 同上,这里的属性是:名字_属性名typeArray.recycle(); //供以后使用。以前取回的可能就是textSize和textColor初始化的那段}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);this.setBackgroundColor(backColor);myPaint.setTextSize(textSize);myPaint.setColor(textColor);myPaint.setStyle(Style.FILL);canvas.drawRect(new Rect(10, 10, 100, 100), myPaint);canvas.drawText(myString, 100, 100, myPaint);}}
(3)、在XML布局文件中,使用该MyView自定义组件。
-
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:test="http://schemas.android.com/apk/res/com.fs.myselfview" //引入名字空间android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><com.fs.myselfview.MyViewstyle="@style/square" //引用自定义的square样式test:backColor="#336699"test:textSize="40px"test:textColor="#996633" /></LinearLayout>
4、attrs中自定义枚举类型的使用。如在定义LinearyLayout中,设置横向排列或是纵向排列时,用到了枚举。
(android:orientation="horizontal")
(1)、在<declare-styleable>中定义。
-
基本格式:<declare-styleable name="名字"><attr name="枚举名称"><enum name="枚举健名" value="枚举值名" /><enum name="枚举健名 " value="枚举值名" /></attr></declare-styleable>实例:<declare-styleable name="MyView"><attr name="textColor" format="color" /><attr name="textSize" format="dimension" /><attr name="backColor" format="color" /><attr name="enums"><enum name="zero" value="0" /><enum name="one" value="1" /></attr></declare-styleable>package com.fs.myselfview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Rect;import android.util.AttributeSet;import android.view.View;public class MyView extends View {private Paint myPaint;private static final String myString = "Welcome to our Zoon!";float textSize;int textColor, backColor, enums;TypedArray typeArray;public MyView(Context context) {super(context);// TODO Auto-generated constructor stub}public MyView(Context context, AttributeSet attr) {super(context, attr);myPaint = new Paint();typeArray = context.obtainStyledAttributes(attr, R.styleable.myView, R.attr.enums, 0);// TypedArray是一个数组容器textSize = typeArray.getDimension(R.styleable.myView_textSize, 30); // 防止在XML文件里没有定义,就加上了默认值30textColor = typeArray.getColor(R.styleable.myView_textColor, 0xFFFFFF); // 同上,这里的属性是:名字_属性名backColor = typeArray.getColor(R.styleable.myView_backColor, 0xFFFFFF);enums = typeArray.getInt(R.styleable.myView_enums, 0); //取得attrs中定义的枚举对象typeArray.recycle();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);this.setBackgroundColor(backColor);myPaint.setTextSize(textSize);myPaint.setColor(textColor);myPaint.setStyle(Style.FILL);canvas.drawRect(new Rect(10, 10, 100, 100), myPaint);canvas.drawText(myString, 100, 100, myPaint);}}
(3)、在布局文件中,使用自定义的MyView控件。
-
在下面例子中的android:orientation="horizontal"和test:enums="one"是一样的。<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:test="http://schemas.android.com/apk/res/com.fs.myselfview"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="horizontal" ><com.fs.myselfview.MyViewstyle="@style/square"test:backColor="#336699"test:textColor="#996633"test:textSize="40px"test:enums="one" /></LinearLayout>
5、标志位、位或运算在attrs中的定义和使用(在Android横坚屏切换中,会有用到)
(1)、定义格式
-
格式:<declare-styleable name="名称"> //name:一般与自定义View类的名称相同<attr name="flagsName"> //name:标志位名称<flag name="flagKey" value="flagValue" /></attr></declare-styleable>实例:<declare-styleable name="SelfView"><attr name="flags"><flag name="stateUnspecified" value="0" /><flag name="stateUnchanged" value="1" /><flag name="stateHidden" value="2" /><flag name="stateAlwaysHidden" value="3" /><flag name="stateVisible" value="4" /><flag name="stateAlwaysVisible" value="5" /><flag name="adjustUnspecified" value="0x00" /><flag name="adjustResize" value="0x10" /><flag name="adjustPan" value="0x20" /><flag name="adjustNothing" value="0x30" /></attr></declare-styleable>
(2)、自定义View控件SelfView。通过TypedArray自取自定义的declare-styleable属性组。取得枚举是类型是通过TypeArray的getInt()函数取得。
-
package com.fs.myselfview;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.View;public class SelfView extends View {TypedArray typeArray;int flags;public SelfView(Context context, AttributeSet attrs) {super(context, attrs);typeArray = context.obtainStyledAttributes(attrs, R.styleable.SelfView, R.attr.flags, 0);flags = typeArray.getInt(R.styleable.SelfView_flags, 0);}}
(3)、在XML布局文件中,使用该SelfView自定义组件。
(在使用自定义View控件时,要引入命名空间)
-
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:test="http://schemas.android.com/apk/res/com.fs.myselfview" //引入命名空间android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><com.fs.myselfview.SelfViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"test:flags="adjustPan|stateVisible"></com.fs.myselfview.SelfView></LinearLayout>