最近在看 Android Programming: The Big Nerd Ranch Guide,书写的不错,推荐级别。打算把看书学到的东西,一点一点记录下来。目前看到24章,讲的是style 和 include。

本章会制作一个简单的遥控器界面。界面最终效果如下:

顶部区域会显示当前频道,再下面那个区域是用来显示正在输入的频道。数字键就是用来输入数字的,Delete键用来清空正在输入的数字,Enter键用来把顶部的频道数字替换为输入的频道数字。就这么简单~

简单界面一

看到上面的显示图片,里面有这么多按钮,你会怎么制作这个界面呢?写个布局文件,然后再添加12个按钮?

我们先写一个只有3个按钮的界面看看效果。布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_remote_control_tableLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="*" > <TextView
android:id="@+id/fragment_remote_control_selectedTextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center"
android:text="0"
android:textSize="50dp" /> <TextView
android:id="@+id/fragment_remote_control_workingTextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="15dp"
android:layout_weight="1"
android:background="#555555"
android:gravity="center"
android:text="0"
android:textColor="#cccccc"
android:textSize="20dp" /> <TableRow android:layout_weight="1" > <Button
android:id="@+id/fragment_remote_control_zeroButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="0" /> <Button
android:id="@+id/fragment_remote_control_oneButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="1" /> <Button
android:id="@+id/fragment_remote_control_enterButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="Enter" />
</TableRow> </TableLayout>

这里使用的布局文件是 TableLayout,用过的应该都知道相关特性,这里还是贴出别人总结好的内容,粘贴内容来自打开链接(我以后也可以看看^_^):

  • 有多少个TableRow对象就有多少行,
  • 列数等于最多子控件的TableRow的列数
  • 直接在TableLayout加控件,控件会占据一行
  • TableLayout属性(也叫全局属性):*代表所有列
  • android:shrinkColumns -------设置可收缩的列,(内容过多,则收缩,扩展到第二行,控件没布满TableLayout时不起作用)
  • android:stretchColumns ------设置可伸展的列,(有空白则填充)
  • 列可以同时具备stretchColumns及shrinkColumns属性
  • android:collapseColumns ------设置要隐藏的列(索引列从0开始)
  • 内部控件属性:
  • android:layout_column -------该单元格在第几列显示
  • android:layout_span    -------该单元格占据列数,默认为1

看完特性,是否能想象出显示效果呢?对于上面的布局文件还有两个地方要说明一下:

  • android:stretchColumns="*" 可以让每列都保持一样的宽度
  • Text 的单位用的是 dp 而不是 sp,是为了让字在不同大小界面上都能保持大小固定不变

显示效果如下:

简单界面二

三个按钮的界面完成了,如果你想给按钮加一个属性的话,这里有三个按钮,你是不是要重复操作三次,如果这里有12个按钮呢?根据我多年的编程经验(大言不惭^_^),如果有一个功能会被用到两次以上,我就会把这个功能封装或者抽象出来。毕竟程序员还是很懒的,能偷懒的地方还是要偷懒。在这里 Android 给出了解决方案,就是使用 style 和 include。

关于 style 是什么,下面这段话摘自Google官方文档(我就不翻译了^_^)。

style is a collection of properties that specify the look and format for a View or window. A style can specify properties such as height, padding, font color, font size, background color, and much more. A style is defined in an XML resource that is separate from the XML that specifies the layout.

Styles in Android share a similar philosophy to cascading stylesheets in web design—they allow you to separate the design from the content.

通过上面的话可以知道,style也是用xml书写,属于resource标签下的内容。和定义 strings.xml 类似,我们也会把 styles.xml 放在 res/values 文件夹下面。

我们在创建工程的时候,Android已经帮我们建好了 styles.xml 文件,现在去 res/values 下就可以看到。你去工程目录下看的话会发现有三个 values文件夹,values,values-v11, values-v14。分别打开文件夹下的 styles.xml 文件,然后看注释,就大概明白这几个文件夹的作用了。我们以 values-v11 下的 styles.xml 来看。

<resources>

    <!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<!-- API 11 theme customizations can go here. -->
</style> </resources>

里面写了一个 style,看名字,是用作程序基本主题显示的,然后看注释就会发现,这个 style 是用于 API 11+(也就是 android 3.0以上)的。通过以上内容,可知这三个文件夹内的 styles.xml是用于不同SDK的,比如说你在这三个文件夹内写的是不同的 styles.xml,那么在android 3.0 + 的机子上读的就是 values-v11 下的 styles.xml,在 android 4.0+的机子上读的就是 values-v14下的 styles.xml,如果是其他版本的系统或者values-v11和values-v14下没有 styles.xml 文件,则系统就会使用values下的styles.xml。好,啰嗦完毕,回归本章。

因为我手机上的系统是4.4.4的,为了简单方便,我只在values-v14下的  styles.xml  中写了新添加的 style。我们把按钮拥有的共同属性提出来,然后作为一个 style 写到 styles.xml中。 写完后的 styles.xml 内容如下(res/values-v14):

<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <!--
Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
</style> <style name="RemoteButton">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:textColor">#556699</item>
<item name="android:textSize">20dp</item>
<item name="android:layout_margin">3dp</item>
</style> </resources>

RemoteButton就是添加的自定义 style。然后把这个style应用到先前写的布局文件中同时把 Button 原有的属性

android:layout_width="0dp"
android:layout_height="match_parent"

删除掉。改变的代码如下:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" >
... <TableRow android:layout_weight="1" > <Button
android:id="@+id/fragment_remote_control_zeroButton"
style="@style/RemoteButton"
android:text="0" /> <Button
android:id="@+id/fragment_remote_control_oneButton"
style="@style/RemoteButton"
android:text="1" /> <Button
android:id="@+id/fragment_remote_control_enterButton"
style="@style/RemoteButton"
android:text="Enter" />
</TableRow> </TableLayout>

这样改变布局代码后,显示效果是一样的,代码也重用了。

正式界面

再看最后的显示效果界面,界面中有4行按钮,每行有3个按钮,一共12个按钮,而且每个按钮基本一样,结合TableLayout特性,我们可以重用TableRow来做出 12 个按钮。

在 res/layout 下面创建一个 button_row.xml 文件,文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android" > <Button style="@style/RemoteButton" />
<Button style="@style/RemoteButton" />
<Button style="@style/RemoteButton" /> </TableRow>

一个 TableRow 中有3个按钮,每个按钮使用名为RemoteButton的style。

再次修改布局文件:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_remote_control_tableLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="*"> <TextView
android:id="@+id/fragment_remote_control_selectedTextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center"
android:text="0"
android:textSize="50dp"/> <TextView
android:id="@+id/fragment_remote_control_workingTextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_margin="15dp"
android:background="#555555"
android:gravity="center"
android:text="0"
android:textColor="#cccccc"/> <!-- <TableRow android:layout_weight="1">
<Button
android:id="@+id/fragment_remote_control_zeroButton"
style="@style/RemoteButton"
android:text="0"/> <Button
android:id="@+id/fragment_remote_control_oneButton"
style="@style/RemoteButton"
android:text="1"/> <Button
android:id="@+id/fragment_remote_control_enterButton"
style="@style/RemoteButton"
android:text="enter"/>
</TableRow> --> <include
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
layout="@layout/button_row" /> <include
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
layout="@layout/button_row"/> <include
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
layout="@layout/button_row"/> <include
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
layout="@layout/bottom_row"/> </TableLayout>

先说明一下,原文章中 include 是这么写的

    <include
android:layout_weight="1"
layout="@layout/button_row" /> <include
android:layout_weight="1"
layout="@layout/button_row" /> <include
android:layout_weight="1"
layout="@layout/button_row" />

但是我写完后,会报错,说是不能单独使用 android:layout_weight属性,要使用的话必须加上 android:layout_width 和 android:layout_height。不明所以,最后还是加上了这两个属性,以至于代码看起来还是有些重复。

这里用到了 include ,include是什么以及干嘛用的呢,摘自别人的话 打开原文链接:还有一篇介绍博客 打开博客

在一个项目中我们可能会需要用到相同的布局设计,如果都写在一个xml文件中,代码显得很冗余,并且可读性也很差,所以我们可以把相同布局的代码单独写成一个模块,然后用到的时候可以通过<include /> 标签来重用layout代码。

这样写完后,我们就有了12个按钮的布局文件了。

Challenge

如何继承自定义的 style 呢?p.s.这部分内容算是课后练习,那本书每章最后都有一个 Challenge,本章的是 Challenge: Style Inheritance 。

如果留意上面写的那个 styles.xml话就会发现,Android自己写那个 "AppBaseTheme" style就继承自"android:Theme.Holo.Light.DarkActionBar"

 <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
</style>

继承自定义的 style 的话,可以有两种方式,一种是如上面 "AppBaseTheme" 所示,用 parent="xxxx"的方式,还有一种可以用 name="父名称.子名称"的方式。

演示xml如下,两种方式都写了一个,继承 "RemoteButton",然后新加了一个 textStyle属性。

    <!-- 第一种继承方式 -->
<style name="OtherButton" parent="RemoteButton">
<item name="android:textStyle">bold</item>
</style> <!-- 第二种继承方式 -->
<style name="RemoteButton.Bold">
<item name="android:textStyle">bold</item>
</style>

仔细看第一张图片的话就会发现, Delete按钮和Enter按钮的字体是粗体。那两个按钮的 style 就是分别使用 "OtherButton","RemoteButton.Bold"。

One More Thing

AppTheme主题bug。

在创建工程时候,eclipse会让你选一个 Theme使用。在下拉列表中有四个选项 None, Holo Dark, Holo Light, Holo Light with Dark Action Bar。这里有个bug,就是不管你选的是  Holo Dark 还是 Holo Light,最后程序使用的还是 Holo Light。

如何解决这个 bug呢,请往下看 ^_^

首先程序使用的主题是声明在 manifest里的

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" > 使用的主题
... </application>

鼠标光标放到 @style/AppTheme处,同时按住 Ctrl 键和鼠标左键,打开AppTheme使用文件。你会发现打开的是 res/values 下面的 styles.xml。然后修改下内容:

<style name="AppBaseTheme" parent="android:Theme.Light">

修改为

<style name="AppBaseTheme" parent="android:Theme">

再打开 res/values-v11下面的 styles.xml 文件,把 AppBaseTheme 主题修改为 android:Theme.Holo。此时就不需要values-v14下的 styles.xml了,把values-v14删掉。这样修改完后,再运行你的程序就可以看到 Holo.Dark生效了。

结语

本章使用的 Activity代码因为使用的是 Fragment,所以没有单独贴出,最后会把程序源码放到附件里,下载看就行了。

工程源码

Android学习之Styles And Includes的更多相关文章

  1. Android学习第三天-打包常用命令

    在前面<Android学习第一天-adb常用命令>和 <Android学习第二天-android常用命令>两篇博文中,我们重点讲解了adb和android的常用命令,下面我们讲 ...

  2. Android学习路线(二十四)ActionBar Fragment运用最佳实践

    转载请注明出处:http://blog.csdn.net/sweetvvck/article/details/38645297 通过前面的几篇博客.大家看到了Google是怎样解释action bar ...

  3. android学习之-Theme和Style

    android学习之-Theme和Style 分类: android 2013-10-11 15:01 960人阅读 评论(0) 收藏 举报 android style和theme的使用. style ...

  4. 《Android学习指南》目录

    源:<Android学习指南>目录 Android学习指南的内容分类: 分类 描述 0.学习Android必备的Java基础知识 没有Java基础的朋友,请不要先看Android的课程,这 ...

  5. 《Android学习指南》文件夹

    转自:http://android.yaohuiji.com/about Android学习指南的内容分类: 分类 描写叙述 0.学习Android必备的Java基础知识 没有Java基础的朋友,请不 ...

  6. 【Android】完善Android学习(六:API 4.0)

    备注:之前Android入门学习的书籍使用的是杨丰盛的<Android应用开发揭秘>,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增 ...

  7. Android学习路线总结,绝对干货

    title: Android学习路线总结,绝对干货 tags: Android学习路线,Android学习资料,怎么学习android grammar_cjkRuby: true --- 一.前言 不 ...

  8. Android 学习资源

    下面这些资源对Android开发来说是很有帮助的! 最常用的: Android开发官方网站:http://developer.android.com/index.html 这个网站应该是Android ...

  9. Android学习资料收集

    1.Android 学习之路 http://stormzhang.com/android/2014/07/07/learn-android-from-rookie/

随机推荐

  1. android 签名验证防止重打包

    网上资料很多,这里只做一个笔记反编译 dex 修改重新打包签名后 apk 的签名信息肯定会改变,所以可以在代码中判断签名信息是否被改变过,如果签名不一致就退出程序,以防止 apk 被重新打包. 1 j ...

  2. Javac的命令(-Xlint)

    在OptionName类中的枚举定义如下: XLINT("-Xlint"), XLINT_CUSTOM("-Xlint:"), -Xlint     Enabl ...

  3. Mac 安装Git

    一.安装 在进行安装前,要说一下,Git和SVN一样,都需要创建一个服务器的,他们都可以创建自己的版本管理服务器.对于个人和小团队来说,使用托管服务器可能更合适. 常见的有Github 和 Bitbu ...

  4. vue-cli 中遇见的问题,记录爬坑日常!

    本片文章我将会记录使用vue-cli 以及一些相关插件遇见的问题和解决方案,另外本文章将会持续更新,本着互联网分享精神,希望我所记录的日常能对大家有所帮助. 1.在img和html文件处于同级阶段,i ...

  5. .Net平台技术介绍、C#语言

    转载别人的  只是用做学习 一.什么是.Net平台? .Net平台是微软搭建的技术平台,技术人员在此平台上进行应用的搭建与开发.它提供了运行所必须的环境.NET Framework类库以及CLR(公共 ...

  6. <深入理解JavaScript>学习笔记(4)_立即调用的函数表达式

    前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行.(小菜理解:的确看到好多,之前都不知道这是自执行匿名函数) 在详细了解这个之前,我们来谈了解一下 ...

  7. HDU 2276 Kiki & Little Kiki 2 矩阵构造

    Kiki & Little Kiki 2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  8. WebService,ASMX文件使用XML格式数据传递参数、验证与获取XML格式返回值的一种方式

    1:首先WebService方法定义,每个方法定义两个参数,一个用于验证权限,string格式的XML文本用于传输数据.最终目的实现,WebService方法,验证权限,获取XML数据,处理之后返回X ...

  9. Thymeleaf学习记录(6)--迭代及条件语法

    迭代: 条件选择: IF-THEN: (if) ? (then) IF-THEN-ELSE: (if) ? (then) : (else) 默认: (value) ?: (defaultvalue) ...

  10. CSS实现文字两端对齐

    最近的项目遇到了这样的需求:(要求标题部分不管文字多少,都必须两端对齐) 如下图: 当时也没有多想直接使用‘ ’进行代替,毕竟产品同学想快一点看到效果,不敢怠慢!不过到第二个页面就傻眼了. 如图: 这 ...