Android界面Style使用总结

本文不包含基础的style使用知识,介绍一点普通入门书上没有或不全的要点。

一、Style的意义

安卓的界面代码分层实际上是Java代码(Activity类等)-》xml-》style,类似于网页开发中的Javascript-》html-》css。个人觉得,Google在设计安卓时,一定是参照了网页的架构。这种架构的好处是,行为、结构、表现分离。

很多人根本没有听过这样的概念,更谈不上理解应用了。在简单的应用中,怎么做都好,于是,在我们入门时,由于对Java比较熟悉,通常很多属于表现层的,例如界面随状态变化,写入了Activity中;结构与表现更不会分离了,全部写入了xml中了。结果就是Java代码越来越臃肿,难以重构、复用、迁移。行为的分离,大家已经接触的比较多了,从MVP到LiveData,Google也推行了很多实践和架构。今天说一说结构与表现的分离。

举个例子,通常应用会分为白天模式和黑夜模式,页面的结构一点变化也没有,只是界面颜色表现不同。这时候应该把不变和变分离出来,把表现相关的代码抽离出来,放入style中。分别写一个白天主题和黑夜主题,设置时,切换sytle即可。

二、Style与Theme的概念

Style(样式)和Theme(主题)从代码实现上来讲一点区别没有。Theme本质上就是一个style,可以用Theme的地方,都可以用style。两者的区别大概是开发者的概念上的约定俗成。Theme通常应用于整个应用、Activity或者整个布局,一般会嵌套子style。Style通常应用于单一View,一般不会再嵌套子style。

三、Style用法总结

使用style,首先要在style.xml或者theme.xml文件中增加项目。这里不再详述。实际上,像尺寸等资源一样,这种xml也是支持多屏幕适配的。当写好style后,如何应用到界面呢?

1.官方文档三种用法及补充用法

官方指引文档介绍了三种用法,都是xml控制。

(1)应用于Application

manifest文件的Application元素可以指定theme属性。

(2)应用于Acitivity

manifest文件的Activity元素可以指定theme属性。

(3)应用于ViewGroup

实际上xml文件中,View的子类都可以指定“style”属性,来应用一个预先写好的style,指定当前View的各种布局等属性值。

如果这个View是一个ViewGroup(继承于View),会有什么效果呢?在5.0以前,这个style只能应用于这个唯一的View,效果和普通View一样。在5.0以后,就厉害了,这个ViewGroup的所有子View、孙View(xml嵌套范畴的)都可以引用当前指定style的中预设的值,这个时候我们更愿意称呼这个style为一个theme了。

再补充几种用法,是Java代码控制。

(4)ContextThemeWrapper

如果要通过代码创建View,我们会调用infalte方法。首先要获取一个Context,这个不难。如果用普通Context就不能再应用style了,可以在基于该context,创建一个ContextThemeWrapper,其构造函数指定了一个style。这样创建的View就可以拥有新的Theme了。

这里有个坑点,使用ContextThemeWrapper以后,很多原本假定context是Acitvity的Api就用不了,比如在xml使用onclick属性。我倒觉得这不一定是ContextThemeWrapper坑,而是这种假定是不应该的。

(5)Dialog构造函数

Dialog的构造函数也可以指定一个style,通常我们会指定一些全屏、不显示状态栏的系统theme。通过继承style,可以增添一些界面的颜色、尺寸值等。

(6)View的构造函数

View函数现在有三个参数的和四个参数的构造函数,也可以指定style。

2.引用Theme中的值

Theme可以定义各种类型的键值对,包括layout属性,尺寸值,颜色值。一旦指定某个布局指定了Theme,xml布局中的子View可以使用问号加key,形如“?key”,引用该Theme中的任意值。

值得注意的是,xml布局中的指定的Drawable也可以引用当前Theme中的值,一般是颜色。这样,不同颜色,相同形状的Shape型Drawable只用写一个xml文件即可。当把同一个Drawable放在不同Theme下,就会呈现不同的颜色。

2.版本兼容性

(1)ViewGroup

manifest中application和activity使用Theme是一直支持的,大概是theme这个概念的来源。

而在xml中,对ViewGroup整体设置Theme,只能5.0以上使用。如果想在低版本对某个部分View使用theme,可以使用上述的代码方式。完全可以实现相同的功能,只是代码多了几行,没有xml指定那么方便。

(2)Drawable

Drawable也是5.0才支持Theme引用。5.0以下只能使用多个Drawbale。

3.Sytle的嵌套与继承的区别

(1)嵌套

嵌套用于扩展。一般会嵌套子Style。在某个Theme中可以直接针对某个View定义一个style,该子style中定义了该子View需要的所有属性。xml中,View可以用style属性本身也可以使用“?”指定方法,引用当前theme定义好的一套属性。

(2)继承

继承除了扩展,还可以覆盖。继承一个父style,可以在此基础上增加新的键值对,实现拓展。也可以覆盖父style的值,实现定制。我们常常覆盖系统style的值。

由于时间能力有限,本文不够详尽,如果有什么问题可以与我讨论。




转载请注明:http://www.aierlanlan.com/rzgz/2555.html