使用风格和主题功能提高界面开发效率

来源:互联网 发布:只有淘宝网打不开 编辑:程序博客网 时间:2024/05/24 06:11

 

软件开发中只有出人意料的创意还是不行的,一款好的软件还需要有让人一见钟情的界面设计。OPhone开发相比于其他平台的一大优势就是使用xml文件来设计软件界面,节省了许多劳动力。 文章介绍如何定义风格和主题的同时也延伸了对自定义组件外观的探讨,从而能够设计出风格更加统一的界面。

风格,是指能应用于布局文件中的单一组件的一套格式属性集合。举个简单的例子,你能为一个TextView组件定义一套风格并在其中指定字体的大小和颜色。

主题,是指能应用于一个或者多个Activity(活动)的一套格式属性的集合。例如,你能定义一个主题,指定窗口框架颜色和面板的前景色和背景色,并且为菜单指定字体的颜色和大小,应用于一个Activity。

这些工作,在以往的编程开发中往往需要用代码来实现,不便于修改。在OPhone中可以像定义布局一样用xml文件来定义风格和主题,使用起来非常方便。你可以使用系统定义好的风格和主题,当然下面讲述的将是如何定义自己的风格和主题。

风格style

定义风格类似于定义String型字符串,回想一下定义字符串时,我们在res/values/下创建文件Strings.xml。然后在<resources></resources>标签里面定义字符串。如下示:

view plaincopy to clipboardprint?

  1. <resources> <string name="hello">Hello World, StyTheme!</string> <string name="app_name">ST</string> </resources> 
<resources> <string name="hello">Hello World, StyTheme!</string> <string name="app_name">ST</string> </resources>

同样在定义style时,也是在res/value目录下新建一个xml文件(文件名可以随便取的)。同样在定义style时,也是在res/value目录下新建一个xml文件(文件名可以随便取的)。并添加<resources> </resources>标签。下面将在<resources> </resources>标签里面添加<style>元素它就像String一样可以直接的使用。但是你必须给他起一个独一无二的名字,像<style name="mytextstyle"></style>。这样你就可以像使用String一样使用Style了。在<style name="mytextstyle"></style>里面才是真正的声明风格属性的地方。每一种属性的声明都需要放在<item>标签下,每一种属性对应一个<item>标签,你可以在这些标签下定义你想要的属性,如字体的大小和颜色等。下面是一个定义风格的文件mystyles.xml:

view plaincopy to clipboardprint?

  1. <resources> <style name="mytextstyle" > <item name="android:textSize">30px</item> <item name="android:textColor">#FFFF0000</item> <item name="android:textStyle">bold</item> <item name="android:typeface">serif </item> </style> </resources> 
<resources> <style name="mytextstyle" > <item name="android:textSize">30px</item> <item name="android:textColor">#FFFF0000</item> <item name="android:textStyle">bold</item> <item name="android:typeface">serif </item> </style> </resources>

上面的代码中,定义一个风格,名字是mytextstyle,并且设定了两个可以应用于字体的属性,textSize和textColor。在item标签里面可以使用任何可以使用的属性,这些属性可以在类R.attr下找到。如前所述,使用style就像使用String一样简单,下面的代码将使用上面定义的style:

view plaincopy to clipboardprint?

  1. <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" style="@style/mytextstyle" /> 
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" style="@style/mytextstyle" />

只需要在xml文件中直接应用就OK了。显示效果如图2:

图1 默认的风格 图2 自定义风格

除了可以完全的自定义风格还可以继承系统的风格如下示:

view plaincopy to clipboardprint?

  1. <resources> <style name="mytextstyle" parent="android:TextAppearance.Large"> <item name="android:textColor">#FFFF0000</item> <item name="android:textStyle">bold</item> <item name="android:typeface">serif </item> </style> </resources> 
<resources> <style name="mytextstyle" parent="android:TextAppearance.Large"> <item name="android:textColor">#FFFF0000</item> <item name="android:textStyle">bold</item> <item name="android:typeface">serif </item> </style> </resources>

效果如图3所示:

图3 继承系统的style 

系统的定义的风格可以在R.style下找到,但是看不到具体的样式,在platforms/android-1.5/data/res/values/styles.xml目录下可以查看样式。一切带有style标签的资源都是可以继承的,也可以继承自己定义的style。

主题theme

主题在定义和引用方式上和风格的定义和使用是一样的,唯一的不同是主题往往应用于一个或多个Activity,而风格往往是用在一个组件上。在使用上,主题可以在AndroidManifest.xml文件中的<application> 和 <activity>标签下使用,还可以通过代码在程序中使用。下面将在mytheme.xml文件中定义主题如下:

view plaincopy to clipboardprint?

  1. <?xml version="1.0" encoding="utf-8" ?> <resources> <style name="myTransparent" > <item name="android:windowBackground">@drawable/transparent_backgroud</item> <item name="android:windowFrame">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:colorForeground">#fff</item> <item name="android:windowFullscreen">true</item> </style> </resources> 
<?xml version="1.0" encoding="utf-8" ?> <resources> <style name="myTransparent" > <item name="android:windowBackground">@drawable/transparent_backgroud</item> <item name="android:windowFrame">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:colorForeground">#fff</item> <item name="android:windowFullscreen">true</item> </style> </resources>

布局文件如下:

view plaincopy to clipboardprint?

  1. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:layout_gravity="center_vertical" style="@style/mytextstyle" /> </LinearLayout> 
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:layout_gravity="center_vertical" style="@style/mytextstyle" /> </LinearLayout>

上面代码中定义主题myTransparent,并设置窗口背景为透明,窗口框无,无标题全屏。同样主题中可以使用的属性资源可以在开发文档的R.attr下找到。显示效果如图4所示:

图 4 自定义主题

那么应该如何使用定义好的主题呢?主题不能在单个的组件上使用,只能用在Activity上,如果想对单一的Activity使用,在Activity标签下设置为

view plaincopy to clipboardprint?

  1. <activity android:theme="@style/myTransparent"> 
<activity android:theme="@style/myTransparent">

若果是对整个的程序中所有的Activity都是用的话,只要这样就行了:

view plaincopy to clipboardprint?

  1. <application android:theme="@style/myTransparent"> 
<application android:theme="@style/myTransparent">

而不必为每个Activity都设置。除了上面完全定义的主题外,还可以像定义风格一样继承系统的主题资源,这样只需要做少量的修改,就可以打造一个完美的主题了。当然这些系统已经设定好的主题资源也可以单独使用,如Theme.Dialog可以使你的Activity看上去更像一个对话框,唯一要注意的地方是,使用系统的主题时要加上android:像这样<activity android:theme="@android:style/Theme.Dialog">。

当然,你也可以在程序中设定主题使用setTheme()方法,但是要注意setTheme()一定要在setContentView()之前调用。否则设定的主题无法表现出来,可以这样使用:

view plaincopy to clipboardprint?

  1. setTheme(R.style.myTransparent); setContentView(R.layout.main); 
 setTheme(R.style.myTransparent); setContentView(R.layout.main);

之所以这样做,是因为主题是不能动态改变的,系统在绘制程序界面的开始就应该先获得主题的信息,才能绘制,而一旦绘制了,就不能再做改变。

进一步统一界面

前面介绍了如何定义风格和主题,虽然这样已经可以为自己的应用打造统一的风格,但是还是不能够做到更好。下面两副图分别是风格统一前后的界面。

图5 系统原来风格 图6 统一风格

在上面的布局中我们用到了ImageView,Button,EditText,TextView这些组件。图5是界面未统一的外观,最上面是灰色的图片,下面有淡蓝色的按钮和编辑框。整个屏幕的背景为黑色,极不相称。图六是统一风格的界面,按钮外观和最上面的图片颜色一致,编辑框背景透明。为了使组件(这里主要是按钮和编辑框)风格和图片统一,我们要更改他们的背景。但是这里的背景并不能简单的用一副图片代替,那样的话按钮在选中,点击时的状态和没有焦点没有点击时的状态一样。看上去就很死板,而且无法判断按钮的状态。所以改动后的background应该是一组图片,这样我就需要了解<selector></selector>标签。在这个标签里定义了一组状态,分别对应组件在有无焦点是否点击时使用的图片。在res/drawable下新建文件btn_default.xml内容如下所示:

view plaincopy to clipboardprint?

  1. <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/btn_default_normal" /> <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/btn_default_normal_disable" /> <item android:state_pressed="true" android:drawable="@drawable/btn_default_pressed" /> <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_default_selected" /> <item android:state_enabled="true" android:drawable="@drawable/btn_default_normal" /> <item android:state_focused="true" android:drawable="@drawable/btn_default_normal_disable_focused" /> <item android:drawable="@drawable/btn_default_normal_disable" /> </selector> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/btn_default_normal" /> <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/btn_default_normal_disable" /> <item android:state_pressed="true" android:drawable="@drawable/btn_default_pressed" /> <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_default_selected" /> <item android:state_enabled="true" android:drawable="@drawable/btn_default_normal" /> <item android:state_focused="true" android:drawable="@drawable/btn_default_normal_disable_focused" /> <item android:drawable="@drawable/btn_default_normal_disable" /> </selector>

这个文件定义了按钮组件处在各种状态时使用的图片,我们要做的只要把图片替换成自己的就OK了,这里将按钮的图片换成和标题图片同样的风格。我使用的图片如图7:

图7 按钮使用的9-PATH图片

为改变编辑框背景同样在res/drawable下新建文件edit_text.xml内容如下:

view plaincopy to clipboardprint?

  1. <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/shape" /> <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled" /> <item android:state_pressed="true" android:drawable="@drawable/textfield_pressed" /> <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_selected" /> <itemandroid:state_enabled="true" android:drawable="@drawable/shape"/> <itemandroid:state_focused="true" android:drawable="@drawable/textfield_disabled_selected" /> <item android:drawable="@drawable/textfield_disabled" /> </selector> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/shape" /> <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled" /> <item android:state_pressed="true" android:drawable="@drawable/textfield_pressed" /> <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_selected" /> <itemandroid:state_enabled="true" android:drawable="@drawable/shape"/> <itemandroid:state_focused="true" android:drawable="@drawable/textfield_disabled_selected" /> <item android:drawable="@drawable/textfield_disabled" /> </selector>

将编辑框失去焦点时的背景做成半透明的,获得焦点时的图片用白色背景代替,使用的图片如图8:

图8 编辑框使用9-PATH图片

这样在大多数情况下,们就可以看到漂亮的屏幕自定义背景图片。这里使用的图片是9-Patch图片,这是一种可以无限拉伸的图片。使用selector标签定义的背景也很容易,像使用风格和主题一样,代码如下:

view plaincopy to clipboardprint?

  1. android:background="@drawable/btn_default"
android:background="@drawable/btn_default"

注意这里引用的是res/drawable下的刚刚定义的btn_default.xml文件名。同样改变编辑框背景时也应该引用文件名。如果使用系统组件外观的话,就会出现许多问题,下面图10是系统组件外观,由于编辑框背景不透明遮挡了背景图片。图9是编辑框背景改成透明后的效果,能看到背景图片(这里使用的是Android模拟器出的效果 图)。

图9 统一风格 图10 风格未统一

注:这里有一个问题,下面的图11和图12分别是风格统一后在OPhone模拟器和Android模拟器下运行后的结果,图11没有显示背景图片(一个钟和四个信封的背景图),图12是Android下的运行结果。在布局文件中更改背景代码如下:

view plaincopy to clipboardprint?

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     android:orientation="vertical"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent"
  5.    android:background="@drawable/back"
  6. >    
  7. 。。。。。。。   
  8. </LinearLayout> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/back" > 。。。。。。。 </LinearLayout>

具体的布局内容可见源码,这里的back既是有一个钟和四个信封的背景图片。

图11   OPhone模拟器下的结果 图12 Android模拟器下的结果

作者介绍:

刘照云,独立开发者。精通Java,Android编程,OPhoneSDN活跃用户账号:ntop。密切关注OPhone动向,坚决为国产系统崛起贡献一份力量。

原创粉丝点击