Android中Styles、Themes、attrs介绍
jopen
11年前
Styles和Themes
在Android中,style被用来指定窗体或视图的样式,比如视图的宽高、补白(padding)、背景,字体颜色等。style不需我们在代码中进行设置,可以在xml文件中按照DTD格式进行配置。
Android中的style其实跟css的思想一样,允许我们把功能实现和外观设计分离开,View配置也提供了html中如id、name属性一样的功能标签style,让我们有能力把所有的样式集中在一个地方,如下一个例子
</div> <? 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>
在上面的布局文件中,三个TextView的android:layout_width、android:layout_height、android:textColor样式属性都一样,这种情况下我们就可以单独定义一个style,以一种更优雅的做法来替代上面的写法
</div>
sample1_style.xml
< 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>
注意:style文件必须在values-*目录中,且必须按照DTD格式来编写各个定义好的标签
接下来就是在View配置中使用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>
使用时只需使用style属性引用我们定义好的style即可,这种方式可以有效的避免做重复性的工作,简化我们的工作
Theme是应用于整个Application、Activity的style,而不是某一个View,如果style被当做Theme来应用时,那么整个应用或整个窗体中的元素都将使用这个风格样式(如果下面的子项不存在某一属性,那么将会被忽略),当然如果为某个特定的View指定了style时,相同的属性会被覆盖。使用 android:theme="@style/mystyle"来指定主题
Styles继承
Android系统为我们提供了一整套的style,比如说显示字符串最基本的style是TextAppearance,它定义了一些最基本
的属性
</div> <style name="TextAppearance"> <item name="android:textColor">?textColorPrimary</item> <item name="android:textColorHighlight">?textColorHighlight</item> <item name="android:textColorHint">?textColorHint</item> <item name="android:textColorLink">?textColorLink</item> <item name="android:textSize">16sp</item> <item name="android:textStyle">normal</item> </style>
还有许多各个方面的style,大家可以参见:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/res/res/values/styles.xml
</div>
如果我们只想改变基础style中的某一项属性时,这时可以使用继承来实现
<style name= "Sample1" parent= "@android:style/TextAppearance" > < item name= "android:textColor" >#00FF00 </item > </style >
使用parent属性来继承一个基础style,这个时候当应用Sample1 style时,只有android:textColor改变了,其它的属性还是使用默认的
当你要继承一个自己定义的style时,不需要使用parent属性来指定,直接可以像下面这样
</div> <style name= "Sample1.Big"> < item name= "android:textSize" >18sp </item > </style >
attrs
attrs看字面意思就是一组属性的集合,那attrs有什么用呢,在自定义View的时候,一般会自定义一些属性,通过构造方法中AttributeSet参数的封装,让我们能够获取到为View配置的属性,至于怎么操作,大家可以参看http://developer.android.com/training/custom-views/index.html 上介绍的这个例子
</div>
Styles、Themes和attrs 之间的关系
首先我们来看一下如何来自定义style中item name,之前我们用的都是Android为我们提供的item name。
第一我们需要定义一个attrs,并指定好数据类型
<resources> <declare-styleable name="ViewPagerIndicator"> <attr name="vpiTabPageIndicatorStyle" format="reference" /> </declare-styleable> </resources>
然后就可以在style中进行引用了
</div> <style name= "Theme.PageIndicatorDefaults" parent = "android:Theme"> <item name ="vpiTabPageIndicatorStyle" >@style/Widget.TabPageIndicator </ item> </style >
接下来我们看View的一个构造方法的定义
public View (Context context, AttributeSet attrs, int defStyle)
Added in API level 1
Perform inflation from XML and apply a class-specific base style. This constructor of View allows subclasses to use their own base style when they are inflating. For example, a Button class's constructor would call this version of the super class constructor and supply R.attr.buttonStyle
for defStyle; this allows the theme's button style to modify all of the base view attributes (in particular its background) as well as the Button class's attributes.
Parameters
context | The Context the view is running in, through which it can access the current theme, resources, etc. |
---|---|
attrs | The attributes of the XML tag that is inflating the view. |
defStyle | The default style to apply to this view. If 0, no style will be applied (beyond what is included in the theme). This may either be an attribute resource, whose value will be retrieved from the current theme, or an explicit style resource. |
第三个参数是关键,揭示了Styles、Themes和attrs三者之间的联系。当自定义View时,如果自定义的View不在布局文件中进行配置,而是通过代码的方式来添加到窗体进行显示,这时我们怎么来为它附加style呢,这时就可以通过这个构造方法来做,首先为Activity配置一个Theme style,然后通过设置第三个参数来引用我们定义好的attr,这样就可以为自定义View附加好样式了
< activity android:name ="tu.bingbing.myviewpager.SampleTabsDefault" android:label ="@string/app_name" android:theme ="@style/Theme.PageIndicatorDefaults" >
public TabView(Context context) { super (context, null, R.attr. vpiTabPageIndicatorStyle); }
参考:</div> http://viewpagerindicator.com/</div>