Microsoft Word - Android 7.x.doc

Size: px
Start display at page:

Download "Microsoft Word - Android 7.x.doc"

Transcription

1 第 4 章 Android GUI 开发 Android 系统提供了丰富的可视化界面组件, 包括菜单 按钮 对话框等 Android 系统采用 Java 程序设计中的 UI 设计思想, 其中包括事件处理机制及布局管理方式 Android 系统中的所有 UI 类都是建立在 View 和 ViewGroup 两个类的基础之上的, 所有 View 的子类称为 Widget, 所有 ViewGroup 的子类称为 Layout 本章将详细介绍 Android N 的基础功能单元 Activity 的用户界面 UI 设计 用户界面 UI 组件及其事件处理的相关知识 4.1 View 和 ViewGroup Activity 是 Android 应用程序与用户交互的接口, 每一个屏幕视图都对应一个 Activity 其实 Activity 本身无法显示在屏幕上, 其更像一个用于装载可显示组件的容器 这就好比一个 JSP 页面, 它本身并没有显示出来任何东西, 负责显示的是 JSP 页面内的各种 HTML 标签, 而 JSP 页面好比一个容器, 负责将这些表情装载到页面内 那么在 Android 应用程序里, 谁才是真正负责显示的那部分呢? 答案是 View 和 ViewGroup, 其中 ViewGroup 是 View 的子类 Android UI 界面是通过 View( 视图 ) 和 ViewGroup 及其派生类组合而成的 其中 View 是所有 UI 组件的基类, 基本上所有的高级 UI 组件都是继承 View 类实现的, 如 TextView( 文本框 ) Button List EditText( 编辑框 ) Checkbox 等 一个 View 在屏幕占据一块矩形区域, 负责渲染这块矩形区域, 也可以处理这块矩形区域发生的事件, 并可以设置该区域是否可见以及获取焦点等 而 ViewGroup 是容纳这些组件的容器, 其本身也是从 View 中派生出来的, 它继承于 Android.view.View, 功能就是装载和管理下一层的 View 对象或 ViewGroup 对象, 也就是说它是一个容纳其他元素的容器, 负责对添加进来的 View 和 ViewGroup 进行管理和布局 View 和 ViewGroup 的关系如图 4.1 所示

2 第 4 章 Android GUI 开发 57 图 4.1 View 和 ViewGroup 的关系图从图 4.1 可以看到,ViewGroup 可以包含一个或任意个 View( 视图 ), 也可以包含作为更低层次的子 ViewGroup, 而子 ViewGroup 又可以包含下一层的叶子节点的 View 和 ViewGroup 这种灵活的层次关系可以形成复杂的 UI 布局 在开发过程中形成的用户界面 UI 一般来自于 View 和 ViewGroup 类的直接子类或者间接子类 例如,View 派生出的直接子类有 AnalogClock ImageView KeyboardView ProgressBar Space SurfaceView TextView TextureView ViewGroup ViewStub 等 ViewGroup 派生出的直接子类有 AbsoluteLayout FragmentBreadCrumbs FrameLayout GridLayout LinearLayout RelativeLayout SlidingDrawer 等 本章不能对 View 和 ViewGroup 的所有子类都进行详细的介绍, 只能简单介绍其中常用的一小部分 如果需要了解各 UI 组件的相关信息, 请参考相关文档 4.2 使用 XML 定义视图 在使用 XML 构建一个用户界面之前, 我们需要重温一下 Android 工程的目录结构 如图 4.2 所示, 以 HelloAndroid 为例,project 视图列出了工程的目录结构 以. 开头的目录是 AS 生成的辅助目录, 无须用户干预 HelloAndroid 文件夹是模块目录, 编程工作主要集中在这个目录中, 相当于使用 Eclipse 构建的工程文件夹, 包含 build src res 等文件夹 其中,res 目录为 Android 工程中所使用的资源目录, 用户 UI 所涉及的资源基本都放置在该目录下 res 目录下的每一项资源文件都会由 AAPT(Android Asset Packaging Tool) 为其生成一个对应的 public static final 类型的 ID 号, 放置到 build 目录下的 R.java 文件中,Android 系统根据该 ID 号来访问对应 图 4.2 Android 工程的目录结构

3 58 Android 7 应用程序开发教程 资源 build 目录由 AS 自动生成, 不需要用户修改, 由系统维护 res/drawable/ 目录用来存放工程中使用到的图片文件,drawable 之后的 hdpi ldpi mdpi 分别放高分辨率 低分辨率和中分辨率的图片以适应不同分辨率的手机,Android 系统会根据用户手机的配置信息自动选取合适分辨率的图片文件, 无须程序员干预 ;res/layout/ 目录下存放着定义 UI 布局文件用的 XML 文件, 默认文件名为 main.xml;res/values/ 目录下存放着用于存储工程中所使用到的一些字符串信息的文件, 默认文件名为 strings.xml 当然, 每个目录下都可以存放多个 XML 文件, 可由开发者自行创建 由此可见,Android 工程中使用的用户 UI 设计以及用户 UI 中涉及的字符串都是由 XML 文件来存储的 Android 系统使用 XML 文件来定义用户视图 单击打开 values 文件夹下的 string.xml 文件显示出如下代码 : <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">hello Android!</string> <string name="app_name">helloandroid</string> </resources> 文件的开头部分 <?xml version="1.0" encoding="utf-8"?> 定义了 XML 的版本号和字符编码, 这个部分在所有的 XML 文件中都会有, 由系统自动添加, 不需要修改 <resources> 标签定义了 hello 和 app_name 两个变量, 可以被 HelloAndroid 工程直接使用 当该文件被修改时,gen 目录下的 R.java 文件也会跟随进行更新 双击 main.xml 文件, 代码如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:id="@id/textview1" android:layout_width="fill_parent" android:text="@string/hello" /> </LinearLayout> <LinearLayout> 标签定义了当前视图使用的是 LinearLayout 布局, 也叫作线性布局, 这是最常用的布局方式,Android SDK 还提供其他的几种布局方式, 我们会在后面的章节中进行详细的介绍 在 <LinearLayout> 标签中定义了该布局方式的相关属性 android: layout_width="fill_parent" 和 android:layout_height="fill_parent" 表示该布局的宽和高充满整个手机屏幕, android:orientation="vertical" 表示该布局中所放入的组件的排列方式为纵向排列 在 <LinearLayout...> 和 </LinearLayout> 之间可以添加各种 UI 组件并设置组件的相关属性, 例如组件的高度 宽度 内容等, 在 4.4 节会详细介绍各种常见组件的使用方法 在 HelloAndroid 实例中添加的是一个 TextView 组件, 相当于一个显示内容的标签 android:layout_width="fill_parent" 指定其宽度覆盖满容器的宽,android:layout_height= "wrap_content" 指定其高度跟随其显示内容变化 android:id="@id/textview1" 指明该 TextView 的 ID 值为 R.java 文件中 ID 类的成员常量 textview1 Android SDK name>:]<resource_type>/<resource_name> 方式, 以便于从 XML 文件中访问工程的资源 android:text="@string/hello" 指明该 TextView 组件显示的内容为

4 第 4 章 Android GUI 开发 59 资源文件 string.xml 中定义的 hello 变量的内容 android:text 属性也可以直接指定要显示的字符串, 但是在实际的工程开发过程中不鼓励这种方式, 而应该使用资源文件中的变量, 因为这样便于工程维护和国际化 在本书中, 为了节省篇幅, 部分显示内容简单的组件使用了字符串直接赋值的方法 Android 工程中使用到的资源文件都会在 gen 目录下的 R.java 中生成对应项, 由系统为每个资源分配一个十六进制的整型数值, 唯一标明每个资源 HelloAndroid 工程中的 R.java 文件代码如下 : package introduction.android.helloandroid; public final class R { public static final class attr { public static final class drawable { public static final int ic_launcher=0x7f020000; public static final class id { public static final int textview1=0x7f050000; public static final class layout { public static final int main=0x7f030000; public static final class string { public static final int app_name=0x7f040001; public static final int hello=0x7f040000; 由该文件可见,R 为静态最终类 其中 public static final class layout 代表的是 res/layout 文件夹的内容,layout 类的每个整型常量代表该文件夹下的一个 XML 布局文件 例如,public static final int main 代表的是 main.xml 文件,0x7f 为系统 main.xml 文件生成的整型数值 在 Android 工程中根据该数值找到 main.xml 文件 public static final class string 代表的是 res/values/strings.xml 文件, string 类中的每个整型常量型成员代表 strings.xml 文件中定义的一个变量 例如,public static final int app_name 代表 strings.xml 中定义的 app_name 变量,public static final int hello 代表 stings.xml 文件中定义的 hello 变量 在工程开发过程中, 可以通过 [<package_name>.]r.<resource_type>.<resource_name> 方式来访问 R 中定义的任意资源 其中 package_name 为资源文件被放置的包路径, 一般可以省略 resource_type 为资源类型, 例如 layout string color drawable menu 等 resource_ name 指的是为资源文件在类中定义的整型常量的名字, 例如 : setcontentview(r.layout.main); 这行代码中, 通过 R.layout.main 找到了布局文件 main.xml, 并通过 setcontentview 方法将其设置为当前 Activity 的视图 要从视图中查找某个组件, 需要使用 findviewbyid 方法, 通过组件 ID 获取组件的对象 例如, 要获取 main.xml 中的 TextView 组件对象, 需要执行以下代码 : TextView textview=(textview)findviewbyid(r.id.textview1);

5 60 Android 7 应用程序开发教程 4.3 布局 Android SDK 定义了多种布局方式以方便用户设计 UI 各种布局方式均为 ViewGroup 类的子类, 结构如图 4.3 所示 本节将对 FrameLayout( 单帧布局 ) LinearLayout( 线性布局 ) AbsoluteLayout ( 绝对布局 ) RelativeLayout( 相对布局 ) 和 TableLayout( 表格布局 ) 进行简单的介绍 图 4.3 Android SDK 布局方式结构图 FrameLayout FrameLayout 又称单帧布局, 是 Android 所提供的布局方式里最简单的布局方式, 它指定屏幕上的一块空白区域, 在该区域填充一个单一对象, 例如图片 文字 按钮等 应用程序开发人员不能为 FrameLayout 中填充的组件指定具体填充位置, 默认情况下, 这些组件都将被固定在屏幕的左上角, 后放入的组件会放在前一个组件上进行覆盖填充, 形成部分遮挡或全部遮挡 开发人员可以通过组件的 android:layout_gravity 属性对组件位置进行适当的修改 实例 FrameLayoutDemo 演示了 FrameLayout 的布局效果 该布局中共有 4 个 TextView 组件, 前 3 个组件以默认方式放置到布局中, 第 4 个组件修改 gravity 属性后放置到布局中, 运行效果如图 4.4 所示 实例 FrameLayoutDemo 中的布局文件 main.xml 的代码如下 : 图 4.4 FrameLayout 的布局效果 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/text1"

6 第 4 章 Android GUI 开发 61 android:textcolor="#00ff00" android:textsize="100dip" android:text="@string/first"/> <TextView <TextView android:id="@+id/text2" android:textcolor="#00ffff" android:textsize="70dip" android:text="@string/second"/> android:id="@+id/text3" android:textcolor="#ff0000" android:textsize="40dip" android:text="@string/third"/> <TextView android:id="@+id/text4" </FrameLayout> 其中 : android:textcolor="#ffff00" android:textsize="40dip" android:layout_gravity="bottom" android:text="@string/forth"/> 表明 FrameLayout 布局覆盖了整个屏幕空间 实例 FrameLayoutDemo 中的 string.xml 文件内容如下 : <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">framelayoutdemo</string> <string name="first"> 第一层 </string> <string name="second"> 第二层 </string> <string name="third"> 第三层 </string> <string name="forth"> 第四层 </string> </resources> 从运行后的结果可见, 前 3 个被放置到 FrameLayout 的 TextView 组件都是以屏幕左上角为基点进行叠加的 第 4 个 TextView 因为设置了 android:layout_gravity="bottom" 属性而显示到了布局的下方 读者可自行将 android:layout_gravity 属性值修改为其他属性, 查看运行效果 LinearLayout LinearLayout 又称线性布局, 该布局应该是 Android 视图设计中最经常使用的布局 该布局可以使放入其中的组件以水平方式或者垂直方式整齐排列, 通过 android:orientation 属性指定具体的

7 62 Android 7 应用程序开发教程 排列方式, 通过 weight 属性设置每个组件在布局中所占的比重 实例 LinearLayoutDemo 演示了 LinearLayout 布局的使用方法, 效果如图 4.5 所示 图 4.5 LinearLayout 的布局效果 实例 LinearLayoutDemo 中的 strings.xml 文件代码如下 : <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">linearlayoutdemo</string> <string name="red">red</string> <string name="yellow">yellow</string> <string name="green">green</string> <string name="blue">blue</string> <string name="row1">row one</string> <string name="row2">row two</string> <string name="row3">row three</string> <string name="row4">row four</string> </resources> 实例 LinearLayoutDemo 中的布局文件 main.xml 代码如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <TextView android:text="@string/red" android:gravity="center_horizontal" android:background="#aa0000" android:layout_height="fill_parent"

8 第 4 章 Android GUI 开发 63 android:layout_weight="1"/> <TextView android:text="@string/green" android:gravity="center_horizontal" android:background="#00aa00" android:layout_height="fill_parent" android:layout_weight="1"/> <TextView android:text="@string/blue" android:gravity="center_horizontal" android:background="#0000aa" android:layout_height="fill_parent" android:layout_weight="1"/> <TextView android:text="@string/yellow" android:gravity="center_horizontal" android:background="#aaaa00" android:layout_height="fill_parent" android:layout_weight="1"/> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <TextView android:text="@string/row1" android:textsize="15pt" android:layout_width="fill_parent" android:layout_weight="1"/> <TextView android:text="@string/row2" android:textsize="15pt" android:layout_width="fill_parent" android:layout_weight="1"/> <TextView android:text="@string/row3" android:textsize="15pt" android:layout_width="fill_parent" android:layout_weight="1"/> <TextView android:text="@string/row4" android:textsize="15pt" android:layout_width="fill_parent" android:layout_weight="1"/> </LinearLayout>

9 64 Android 7 应用程序开发教程 </LinearLayout> 该布局中放置了两个 LinearLayout 布局对象 第一个 LinearLayout 布局通过 android: orientation="horizontal" 属性将布局设置为横向线性排列, 第二个 LinearLayout 布局通过 android:orientation="vertical" 属性将布局设置为纵向线性排列 每个 LinearLayout 布局中都放入了 4 个 TextView, 并通过 android:layout_weight 属性设置每个组件在布局中所占的比重相同, 即各组件大小相同 layout_weight 用于定义一个线性布局中某组件的重要程度 所有的组件都有一个 layout_weight 值, 默认为 0, 意思是需要显示多大的视图就占据多大的屏幕空间 若赋值为大于 0 的值, 则将可用的空间分割, 分割的大小取决于当前的 layout_weight 数值与其他空间的 layout_weight 值的比率, 例如水平方向上有两个按钮, 每个按钮的 layout_weight 数值都设置为 1, 那么这两个按钮平分宽度 ; 若第一个为 1, 第二个为 2, 则可将空间的三分之一分给第一个, 三分之二分给第二个 将 LinearLayoutDemo 中水平 LinearLayout 的第 4 个 TextView 的 android:layout_weight 属性赋值为 2, 运行效果如图 4.6 所示 LinearLayout 布局可使用嵌套 活用 LinearLayout 布局可以设计出各种各样漂亮的布局方式 RelativeLayout 图 4.6 修改 android:layout_weight 属性 RelativeLayout 又称相对布局 从名称上可以看出, 这种布局方式是以一种让组件以相对于容器或者相对于容器中的另一个组件的相对位置进行放置的布局方式 RelativeLayout 布局提供了一些常用的布局设置属性用于确定组件在视图中的相对位置 相关属性及其所代表的含义列举在表 4.1 中 表 4.1 RelativeLayout 布局常用属性 属性 android:layout_above android:layout_below android:layout_toleftof android:layout_torightof android:layout_alignbottom android:layout_alignbaseline android:layout_aligntop android:layout_alignbottom android:layout_alignleft android:layout_alignright android:layout_alignparenttop android:layout_alignparentbottom 描述将该组件的底部置于给定 ID 的组件之上将该组件的底部置于给定 ID 的组件之下将该组件的右边缘与给定 ID 的组件左边缘对齐将该组件的左边缘与给定 ID 的组件右边缘对齐将该组件的底边与给定 ID 的组件底边对齐将该组件的 baseline 与给定 ID 的 baseline 对齐将该组件的顶部边缘与给定 ID 的顶部边缘对齐将该组件的底部边缘与给定 ID 的底部边缘对齐将该组件的左边缘与给定 ID 的左边缘对齐将该组件的右边缘与给定 ID 的右边缘对齐为 true, 将该组件的顶部与其父组件的顶部对齐为 true, 将该组件的底部与其父组件的底部对齐

10 第 4 章 Android GUI 开发 65 属性 android:layout_alignparentleft android:layout_alignparentright android:layout_centerhorizontal android:layout_centervertical android:layout_centerinparent 描述为 true, 将该组件的左侧与其父组件的左侧对齐为 true, 将该组件的右侧与其父组件的右侧对齐为 true, 将该组件置于水平居中为 true, 将该组件置于垂直居中为 true, 将该组件置于父组件的中央 ( 续表 ) 实例 RelativeLayoutDemo 演示了相对布局的使用方法, 其运行效果如图 4.7 所示 图 4.7 RelativeLayout 布局效果 实例 RelativeLayoutDemo 中的布局文件 main.xml 代码如下 : <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android=" <TextView android:id="@+id/label" android:layout_width="fill_parent" android:text="@string/hello" /> <EditText android:id="@+id/enter" android:layout_width="fill_parent" android:layout_alignparentleft="true" android:layout_below="@+id/label" /> <Button android:id="@+id/button1" android:layout_alignparentright="true" android:layout_below="@+id/enter" android:text="@string/but1text" />

11 66 Android 7 应用程序开发教程 <Button android:id="@+id/ok" android:layout_alignbottom="@+id/button1" android:layout_alignparentleft="true" android:text="@string/but2text" /> </RelativeLayout> 该 RelativeLayout 布局的过程如下 : 放置一个 ID 为 label 的 TextView 组件 通过 android:layout_below="@+id/label" 属性将 ID 为 enter 的组件 EditText 放置到 TextView 的下面 在布局中加入一个 ID 为 button1 的 Button, 通过 android:layout_below="@+ id/enter" 属性将该 Button 放置到 enter 的下面, 通过 android:layout_alignparentright= "true" 属性将 Button 放置到相对布局的右侧 在相对布局中加入一个名为 ok 的 Button, 通过 android:layout_alignbottom="@+ id/button1" 属性将该 Button 底边与 button1 对齐, 通过 android:layout_alignparentleft ="true" 属性将该 Button 放置到布局的左边 TableLayout TableLayout 又称为表格布局, 以行列的方式管理组件 TableLayout 布局没有边框, 可以由多个 TableRow 对象或者其他组件组成, 每个 TableRow 可以由多个单元格组成, 每个单元格是一个 View TableRow 不需要设置宽度 layout_width 和高度 layout_height, 其宽度一定是 match_parent, 即自动填满父容器, 高度一定为 wrap_content, 即根据内容改变高度 但对于 TableRow 中的其他组件来说, 是可以设置宽度和高度的, 只是必须是 wrap_content 或者 fill_parent 实例 TableLayoutDemo 演示了使用 TableLayout 制作 UI 的方法, 效果如图 4.8 所示 实例 TableLayoutDemo 中 strings.xml 的代码如下 : 图 4.8 TableLayout 布局效果 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">hello World, TableLayout!</string> <string name="app_name">tablelayoutdemo</string> <string name="column1"> 第一行第一列 </string> <string name="column2"> 第一行第二列 </string> <string name="column3"> 第一行第三列 </string> <string name="empty"> 最左面的可伸缩 TextView</string> <string name="row2column2"> 第二行第三列 </string> <string name="row2column3">end</string>

12 第 4 章 Android GUI 开发 67 <string name="merger"> 合并三个单元格 </string> </resources> 实例 TableLayoutDemo 中的布局文件 main.xml 的代码如下 : <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TableRow> <TextView android:text="@string/column1" /> <TextView android:text="@string/column2" /> <TextView android:text="@string/column3" /> </TableRow> <TextView android:background="#fff000" android:text=" 单独的一个 TextView" android:gravity="center"/> <TableRow> <Button android:text="@string/merger" android:layout_span="3" android:gravity="center_horizontal" android:textcolor="#f00" /> </TableRow> <TextView android:background="#fa05" android:text=" 单独的一个 TextView"/> <TableRow > <TextView android:text="@string/empty" /> <Button android:text="@string/row2column2" /> <Button android:text="@string/row2column3" /> </TableRow> </TableLayout> 布局文件 main.xml 在 TableLayout 布局内添加了两个 TableRow 和两个 TextView, 形成了如图 4.8 所示的效果 从运行效果看, 第一行和第五行都没能完全显示 TableLayout 布局提供了几个特殊属性, 可以实现以下特殊效果 android:shrinkcolumns 属性 : 该属性用于设置可收缩的列 当可收缩的列太宽以至于布局内的其他列不能完全显示时, 可收缩列会纵向延伸, 压缩自己所占的空间, 以便于其他列可以完全显示出来 android:shrinkcolumns= 1 表示将第 2 列设置为可收缩列, 列数从 0 开始

13 68 Android 7 应用程序开发教程 android:stretchcolumns 属性 : 该属性用于设置可伸展的列 可伸展的列会自动扩展长度以填满所有可用空间 android:stretchcolumns= 1 表示将第 2 列设置为可伸展的列 android:collapsecolumns 属性 : 该属性用于设置隐藏列 android:collapsecolumns= 1 表示将第 2 列隐藏不显示 在 <TableLayout> 标签添加属性 android:shrinkcolumns="0", 再次运行, 效果如图 4.9 所示, 可以看出第一行和第五行都完全显示出来了 图 4.9 完全显示的效果 AbsoluteLayout AbsoluteLayout 又称绝对布局, 放入该布局的组件需要通过 android:layout_x 和 android:layout_y 两个属性指定其准确的坐标值, 并显示在屏幕上 理论上,AbsoluteLayout 布局可用以完成任何的布局设计, 灵活性很大, 但是在实际的工程应用中不提倡使用这种布局 因为使用这种布局不但需要精确计算每个组件的大小, 增大运算量, 而且当应用程序在不同屏幕尺寸的手机上运行时会产生不同效果 实例 AbsoluteLayoutDemo 演示了 AbsoluteLayout 布局的使用方法, 效果如图 4.10 所示 图 4.10 AbsoluteLayout 布局效果

14 第 4 章 Android GUI 开发 69 实例 AbsoluteLayoutDemo 的布局文件 main.xml 代码如下 : <?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_x="10px" android:layout_y="10px" android:text="@string/hello"> </TextView> <TextView android:layout_x="80px" android:layout_y="80px" android:text="@string/action"> </TextView> <TextView android:layout_x="150px" android:layout_y="150px" android:text="@string/hello"> </TextView> </AbsoluteLayout> 其中 : android:layout_x="80px" android:layout_y="80px" 表示将组件放置到以屏幕左上角为坐标原点的坐标系下,x 值为 80 像素 y 值为 80 像素的位置 在这里简单介绍一下 Android 系统常用的尺寸类型的单位 像素 : 缩写为 px 表示屏幕上的物理像素 磅 :points, 缩写为 pt 1pt 等于 1 英寸的 1/72, 常用于印刷业 放大像素 :sp 主要用于字体的显示,Android 默认使用 sp 作为字号单位 密度独立像素 : 缩写为 dip 或 dp 该尺寸使用 160dp 的屏幕作为参考, 然后用该屏幕映射到实际屏幕, 在不同分辨率的屏幕上会有相应的缩放效果以适用于不同分辨率的屏幕 若用 px 的话,320px 占满 HVGA 的宽度, 到 WVGA 上就只能占一半不到的屏幕了, 那一定不是你想要的 毫米 :mm

15 70 Android 7 应用程序开发教程 WebView WebView 组件是 AbsoluteLayout 的子类, 用于显示 Web 页面 借助于 WebView, 可以方便地开发自己的网络浏览器 此处仅对 WebView 的基本用法进行介绍, 在后面进行 Web App 的学习时会有更进一步的讲解 创建工程 WebViewDemo, 为其在 AndroidManifest.xml 文件中添加 Internet 访问权限 : <uses-permission android:name="android.permission.internet" /> 在布局文件 main.xml 中添加一个 WebView 组件 Main.xml 内容如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <WebView android:id="@+id/webview1" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> 实例 WebViewDemo 中的 Activity 文件 WebViewDemoActivity.java 代码如下 : package introduction.android.webview; import android.app.activity; import android.os.bundle; import android.webkit.webview; public class WebViewDemoActivity extends Activity { private WebView webview; /** Called when the activity is first created. */ public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.main); webview=(webview)findviewbyid(r.id.webview1); webview.getsettings().setjavascriptenabled(true); webview.loadurl(" 运行效果如图 4.11 所示

16 第 4 章 Android GUI 开发 71 图 4.11 WebViewDemo 运行界面 4.4 常用 Widget 组件 在前面的章节讲解了用户界面 UI 设计中布局方面的知识, 其中涉及少数几个常用的组件, 例如按钮 文本框等 在这一节中着重讲解 Android 用户 UI 设计中常用的各种组件的用法 Android SDK 提供了名为 android.widget 的包, 其中提供了在应用程序界面设计中大部分常用的 UI 可视组件 之前章节中涉及的各种布局以及文本框 按钮等组件都包含在这个包中 Android 提供了强大的用户 UI 功能, 要设计自己独特的应用程序界面, 需要对各个组件有一个详细的了解 创建 Widget 组件实例 在 Android Studio 中创建一个新的工程, 名字为 WidgetDemo, 用于对各种常见 UI 组件进行学习 下面是工程实现的步骤, 在后续的章节中不会再赘述该过程 新建项目 单击 File New New Project, 打开 New Android Project 对话框, 如图 4.12 所示 输入工程名称 WidgetDemo, 在 Location 后的文本框中输入工程的保存路径, 单击 Next 按钮后, 选择 API24:Android 7.0, 再次单击 Next 按钮 选择 EmptyActivity, 确定 Activity 名字和 Layout 文件的名字, 单击 Finish 按钮, 则 AS 会生成工程目录和相关文件 若需要向以前版本兼容, 则勾选 Backwards Compatibility(AppCompat) 复选框即可 本书中默认不勾选

17 72 Android 7 应用程序开发教程 图 4.12 新建项目 WidgetDemoActivity.java 文件是当前应用程序的入口类 WidgetDemoActivity 的定义文件 双击 WidgetDemoActivity.java, 发现已经为其生成代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; public class WidgetDemoActivity extends Activity { /** Called when the activity is first created. */ public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.main); 其中,onCreate() 方法中的 setcontentview(r.layout.main) 表明 WidgetDemoActivity 使用的用户界面 UI 文件为 main.xml 双击 main.xml 文件, 发现提供了 Graphical Layout 和 main.xml 两种浏览方式 其中 Graphical Layout 方式为以图形方式浏览 main.xml 文件, 其效果等同于 main.xml 在手机设备上运行的效果 ; main.xml 方式为以代码方式浏览 main.xml 文件 这两种方式是等效的, 都可以对 main.xml 文件进行编辑和查看 单击 main.xml 标签, 发现已经为其生成代码如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:text="@string/hello" /> </LinearLayout> 该文件表明, 当前 main.xml 文件所使用的布局为 LinearLayout 布局, 该布局自动填满整个手

18 第 4 章 Android GUI 开发 73 机屏幕 在该布局中, 放置了一个 TextView 组件, 该 TextView 显示的内容为 "@string/hello", 表示 string.xml 文件中定义的 hello 变量的内容 双击 values 目录下的 string.xml 文件, 会发现 hello 变量对应的值为 Hello World, WidgetDemoActivity! 单击 main.xml 的 Graphical Layout 浏览方式, 可查看当前文件的图形化效果, 如图 4.13 所示 图 4.13 文件的图形化效果程序开发人员可以在该图形方式下将左侧的各种组件直接拖曳到屏幕上, 形成自己想要的布局, 也可以直接修改 main.xml 文件的代码 在后续章节中, 在对布局文件进行修改时, 若非特殊情况, 将不再单独描述 按钮 按钮 (Button) 应该是用户交互中使用最多的组件, 在很多应用程序中都很常见 当用户单击按钮的时候, 会有相对应的响应动作 下面在 WidgetDemo 工程的主界面 main.xml 中放置一个名为 Button 的按钮 文件代码如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:text="@string/hello" /> <Button android:id="@+id/button1" android:text="button" />

19 74 Android 7 应用程序开发教程 </LinearLayout> 其中 : <Button android:id="@+id/button1" android:text="button" /> 表明在用户界面上放置了一个 ID 为 button1 的按钮, 按钮的高度 (layout_height) 和宽度 (layout_width) 都会根据实际内容调整 (wrap_content), 按钮上显示文字为 Button, 其运行效果如图 4.14 所示 图 4.14 Button 的应用界面按钮最重要的用户交互事件是 单击 事件 下面为 Button1 添加事件监听器和相应的单击事件 该过程在 WidgetDemoActivity.java 文件中完成, 代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; import android.util.log; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; public class WidgetDemoActivity extends Activity { /** Called when the activity is first created. */ public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.main); Button btn=(button)this.findviewbyid(r.id.button1); btn.setonclicklistener(new OnClickListener(){ public void onclick(view v){ settitle("button1 被用户点击了 "); ); Log.i("widgetDemo", "button1 被用户点击了 ");

20 第 4 章 Android GUI 开发 75 在 WidgetDemoActivity 的 oncreate() 方法中, 通过 findviewbyid(r.id.button1) 方法获得 Button1 的对象, 通过 setonclicklistener() 方法为 Button1 设置监听器 此处新建了一个实现 OnClickListener 接口的匿名类作为监听器, 并实现了 onclick() 方法 当 Button1 被点击时, 当前应用程序的标题被设置成 button1 被用户点击了, 对应在 LogCat 中也会打印相应的字符串, 运行结果如图 4.15 所示 图 4.15 点击按钮运行效果 文本框 文本框 (TextView) 是用于在界面上显示文字的组件, 其显示的文本不可被用户直接编辑 程序开发人员可以设置 TextView 的字体大小 颜色 样式等属性 在工程 WidgetDemo 的 main.xml 中添加一个 TextView, 代码如下 : <TextView android:id="@+id/textview1" android:text="textview" /> 运行效果如图 4.16 所示 修改 Button1 的单击事件为 : public void onclick(view view){ 图 4.16 TextView 的应用界面 //settitle("button1 被用户单击了 ");

21 76 Android 7 应用程序开发教程 Log.i("widgetDemo", "button1 被用户单击了 "); TextView textview=(textview)findviewbyid(r.id.textview1); textview.settext(" 设置 TextView 的字体 "); textview.settextcolor(color.red); textview.settextsize(typedvalue.complex_unit_sp, 20); textview.settypeface(typeface.defaultfromstyle(typeface.bold)); 当 Button1 被单击时, 通过 settext() 方法更改 textview 的显示内容为 设置 TextView 的字体, 通过 settextcolor() 方法修改 textview 显示字体的颜色为红色, 通过 settextsize() 方法修改 textview 显示字体的大小为 20sp, 通过 settypeface() 方法修改 textview 显示字体的风格为加粗, 如图 4.17 所示 图 4.17 单击按钮运行效果 当然, 该过程也可以通过修改 main.xml 文件来实现 将 TextView 标签按照如下代码修改也可以得到同样的效果, 但是失去了应用程序中与用户交互的过程 : <TextView android:id="@+id/textview1" android:text=" 设置 TextView 的字体 " android:textcolor="#ff0000" android:textsize="20sp" android:textstyle="bold"/> 编辑框 编辑框 (EditText) 是 TextView 的子类, 在 TextView 的基础上增加了文本编辑功能, 用于处理用户输入, 例如登录框等, 是非常常用的组件 在工程 WidgetDemo 的 main.xml 文件中添加一个 EditText, 并实现这个功能 : 用户在 EditText 中输入信息的同时, 用一个 TextView 显示用户输入的信息 工程 WidgetDemo 中的布局文件 main.xml 中增加的代码如下 : <EditText android:id="@+id/edittext1" android:layout_width="match_parent" > 在 WidgetDemoActivity 的 oncreate() 方法中添加下列代码 :

22 第 4 章 Android GUI 开发 77 edittext=(edittext)findviewbyid(r.id.edittext1); edittext.addtextchangedlistener(new TextWatcher(){ public void aftertextchanged(editable s){ public void beforetextchanged(charsequence s, int start, int count, int after){ public void ontextchanged(charsequence s, int start, int before, int count){ String text=edittext.gettext().tostring(); textview.settext(text); ); 运行结果如图 4.18 所示 图 4.18 EditText 的应用界面 多项选择按钮 多项选择按钮 (CheckBox) 属于输入型组件, 该组件允许用户一次选择多个选项 当用户不方便在手机屏幕上直接进行输入操作时, 该组件的使用显得尤为方便 下面通过实例讲解 CheckBox 的使用方法 该实例的运行效果如图 4.19 所示

23 78 Android 7 应用程序开发教程 图 4.19 CheckBox 的应用界面 在工程 WidgetDemo 的布局文件 main.xml 文件中添加一个 Button, 代码如下 : <Button android:id="@+id/button2" android:text="checkboxdemo" /> 当该 Button 被用户单击时, 启动一个名为 CheckBoxActivity 的 Activity, 在该 Activity 中演示 CheckBox 的使用方法 启动 CheckBoxActivity 的相关代码如下 : Button ckbtn=(button)this.findviewbyid(r.id.button2); ckbtn.setonclicklistener(new OnClickListener(){ ); public void onclick(view v){ Intent intent=new Intent(WidgetDemoActivity.this,CheckBoxActivity.class); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name="checkboxactivity"></activity> CheckBoxActivity 所使用的布局文件为 checkbox.xml, 使用 LinearLayout 布局, 其中放置了一个 TextView 和三个 CheckBox Checkbox.xml 的文件内容如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">

24 第 4 章 Android GUI 开发 79 <TextView android:id="@+id/text" android:layout_width="fill_parent" android:text="@string/checkboxhello"/> <CheckBox android:id="@+id/checkbox1" android:text="@string/football"/> <CheckBox android:id="@+id/checkbox2" android:text="@string/song"/> <CheckBox android:id="@+id/checkbox3" android:text="@string/book"/> </LinearLayout> 这 4 个组件在对应的 strings.xml 文件中定义的变量为 : <string name="checkboxhello"> 你的爱好是 :</string> <string name="football"> 篮球 </string> <string name="song"> 听歌曲 </string> <string name="book"> 看书 </string> 当用户对多项选择按钮进行选择时, 为了确定用户选择的是哪几项, 需要对每个多项选择按钮进行监听 CompoundButton.OnCheckedChangedListener 接口可用于对 CheckBox 的状态进行监听 当 CheckBox 的状态在未被选中和被选中之间变化时, 该接口的 oncheckedchanged() 方法会被系统调用 CheckBox 通过 setoncheckedchangelistener() 方法将该接口对象设置为自己的监听器 CheckBoxActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; import android.widget.checkbox; import android.widget.compoundbutton; import android.widget.textview; public class CheckBoxActivity extends Activity { private TextView textview; private CheckBox bookcheckbox; private CheckBox songcheckbox; private CheckBox footbacheckbox; protected void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate);

25 80 Android 7 应用程序开发教程 this.setcontentview(r.layout.checkbox); textview=(textview)findviewbyid(r.id.text); footbacheckbox=(checkbox)findviewbyid(r.id.checkbox1); songcheckbox=(checkbox)findviewbyid(r.id.checkbox2); bookcheckbox=(checkbox)findviewbyid(r.id.checkbox3); footbacheckbox.setoncheckedchangelistener(new CompoundButton.OnCheckedChangeListener(){ public void oncheckedchanged(compoundbutton buttonview, boolean ischecked){ ); if(footbacheckbox.ischecked()){ textview.append(footbacheckbox.gettext().tostring()); else { if(textview.gettext().tostring().contains(" 足球 ")){ textview.settext(textview.gettext().tostring().replace(" 足球 ", "")); songcheckbox.setoncheckedchangelistener(new CompoundButton.OnCheckedChangeListener(){ ); public void oncheckedchanged(compoundbutton buttonview, boolean ischecked){ if(songcheckbox.ischecked()){ textview.append(songcheckbox.gettext().tostring()); else { if(textview.gettext().tostring().contains(" 唱歌 ")){ textview.settext(textview.gettext().tostring().replace(" 唱歌 ", "")); bookcheckbox.setoncheckedchangelistener(new CompoundButton.OnCheckedChangeListener(){ ); public void oncheckedchanged(compoundbutton buttonview, boolean ischecked){ if(bookcheckbox.ischecked()){ textview.append(bookcheckbox.gettext().tostring()); else { if(textview.gettext().tostring().contains(" 读书 ")){ textview.settext(textview.gettext().tostring().replace(" 读书 ", ""));

26 第 4 章 Android GUI 开发 81 CheckBoxActivity 为 Checkbox.xml 文件中的三个 CheckBox 分别添加了监听器 当 CheckBox 的状态发生改变时, 通过 Checkbox.isChecked() 方法可以获取当前 CheckBox 按钮的选中状态, 进而进行处理 单项选择按钮组 RadioGroup 为单项选择按钮组, 其中可以包含多个 RadioButton, 即单选按钮, 它们共同为用户提供一种多选一的选择方式 在多个 RadioButton 被同一个 RadioGroup 包含的情况下, 多个 RadioButton 之间自动形成互斥关系, 仅有一个可以被选择 单选按钮的使用方法和 CheckBox 的使用方法高度相似, 其事件监听接口使用的是 RadioGroup.OnCheckedChangeListener(), 使用 setoncheckedchangelistener() 方法将监听器设置到单选按钮上 按照 CheckBox 的讲解思路, 启动一个名为 RadioGroupActivity 的 Activity 来对 RadioGroup 进行讲解 RadioGroupActivity 的运行效果如图 4.20 所示 图 4.20 RadioGroup 的应用界面 在工程 WidgetDemo 的布局文件 main.xml 中添加一个 Button, 并启动 RadioGroupActivity 的相关代码 在 main.xml 中添加代码如下 : <Button android:id="@+id/button3" android:text="radiogroupdemo" /> 启动处理 RadioGroup 的 Activity RadioGroupActivity 的代码如下 : Button radiotn=(button)this.findviewbyid(r.id.button3); radiotn.setonclicklistener(new OnClickListener(){ public void onclick(view v){

27 82 Android 7 应用程序开发教程 ); Intent intent=new Intent(WidgetDemoActivity.this,RadioGroupActivity.class); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name=" RadioGroupActivity "></activity> RadioGroupActivity 使用的是 radiogroup.xml, 其代码如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/radiohello" android:layout_width="fill_parent" android:text="@string/hello"/> <RadioGroup android:id="@+id/radiogroup1" > android:orientation="vertical" android:layout_x="3px" <RadioButton android:id="@+id/radiobutton1" android:text="@string/football" /> <RadioButton android:id="@+id/radiobutton2" android:text="@string/bascketball" /> <RadioButton /> </RadioGroup> android:id="@+id/radiobutton3" android:text="@string/badminton" </LinearLayout> 该布局文件使用了 LinearLayout 布局, 并且在其中放置了一个 TextView 和一个 RadioGroup RadioGroup 中含有三个 RadioButton 这些组件对应的 strings.xml 文件中定义的变量为 :

28 第 4 章 Android GUI 开发 83 <string name="radiohello"> 你最喜欢的运动是 :</string> <string name="bascketball"> 篮球 </string> <string name="badminton"> 羽毛球 </string> <string name="football"> 足球 </string> RadioGroupActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; import android.widget.radiobutton; import android.widget.radiogroup; import android.widget.textview; public class RadioGroupActivity extends Activity { private TextView textview; private RadioGroup radiogroup; private RadioButton radio1,radio2,radio3; public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.radiogroup); textview=(textview)findviewbyid(r.id.radiohello); radiogroup=(radiogroup)findviewbyid(r.id.radiogroup1); radio1=(radiobutton)findviewbyid(r.id.radiobutton1); radio2=(radiobutton)findviewbyid(r.id.radiobutton2); radio3=(radiobutton)findviewbyid(r.id.radiobutton3); radiogroup.setoncheckedchangelistener(new RadioGroup.OnCheckedChangeListener(){ public void oncheckedchanged(radiogroup group, int checkedid) { ); String text=" 我最喜欢的运动是 "; if(checkedid==radio1.getid()){ text+=radio1.gettext().tostring(); textview.settext(text); else if(checkedid==radio2.getid()){ text+=radio2.gettext().tostring(); textview.settext(text); else if(checkedid==radio3.getid()){ text+=radio3.gettext().tostring(); textview.settext(text); 在 RadioGroupActivity 的 oncreate() 方法中为 RadioGroup 添加监视器 RadioGroup OnCheckedChangeListener 在其回调方法 oncheckedchanged() 中对三个 RadioButton 分别进行处理 需要说明的是, 如果把 RadioGroup 去掉, 只使用 RadioButton 的话, 则需要为每个 RadioButton 单独设置监听器, 其使用方法和 CheckBox 没有任何区别

29 84 Android 7 应用程序开发教程 下拉列表 Spinner 提供下拉列表式的输入方式, 该方法可以有效节省手机屏幕上的显示空间 下面用一个简单的实例讲解 Spinner 的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个 Button, 用以启动 SpinnerActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button4" android:text="spinnerdemo" /> 单击 Button 并启动 SpinnerActivity 的代码如下 : Button spinnerbtn=(button)this.findviewbyid(r.id.button4); spinnerbtn.setonclicklistener(new OnClickListener(){ ); public void onclick(view v){ Intent intent=new Intent(WidgetDemoActivity.this,SpinnerActivity.class); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name=" SpinnerActivity "></activity> SpinnerActivity 的运行效果如图 4.21 所示 图 4.21 Spinner 的应用界面 SpinnerActivity 使用的布局文件为 spiner.xml, 其代码如下 : <?xml version="1.0" encoding="utf-8"?>

30 第 4 章 Android GUI 开发 85 <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/textview1" android:text="textview"/> <Spinner android:id="@+id/spinner1" android:layout_width="match_parent" /> </LinearLayout> SpinnerActivity.java 文件的代码如下 : package introduction.android.widgetdemo; import java.util.arraylist; import java.util.list; import android.app.activity; import android.os.bundle; import android.view.motionevent; import android.view.view; import android.widget.adapterview; import android.widget.arrayadapter; import android.widget.spinner; import android.widget.textview; list); public class SpinnerActivity extends Activity { private List<String>list=new ArrayList<String>(); private TextView textview; private Spinner spinnertext; private ArrayAdapter<String>adapter; public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.spiner); // 第一步 : 定义下拉列表内容 list.add(" 沈阳 "); list.add(" 天津 "); list.add(" 北京 "); list.add(" 上海 "); list.add(" 深圳 "); textview=(textview)findviewbyid(r.id.textview1); spinnertext=(spinner)findviewbyid(r.id.spinner1); // 第二步 : 为下拉列表定义一个适配器 adapter=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, // 第三步 : 设置下拉列表下拉时的菜单样式 adapter.setdropdownviewresource (android.r.layout.simple_spinner_dropdown_item); // 第四步 : 将适配器添加到下拉列表上 spinnertext.setadapter(adapter);

31 86 Android 7 应用程序开发教程 { // 第五步 : 添加监听器, 为下拉列表设置事件的响应 spinnertext.setonitemselectedlistener(new Spinner.OnItemSelectedListener(){ public void onitemselected(adapterview<?>arg0, View arg1, int arg2, long arg3) /* 将所选 spinnertext 的值带入 mytextview 中 */ textview.settext(" 我来自 :"+adapter.getitem(arg2)); /* 将 spinnertext 显示 */ arg0.setvisibility(view.visible); public void onnothingselected(adapterview<?>arg0){ textview.settext("none"); arg0.setvisibility(view.visible); ); // 将 spinnertext 添加到 OnTouchListener 对内容选项触屏事件处理 spinnertext.setontouchlistener(new Spinner.OnTouchListener(){ public boolean ontouch(view v, MotionEvent event){ ); // 将 myspinner 隐藏 v.setvisibility(view.invisible); Log.i("spinner","Spinner Touch 事件被触发!"); return false; // 焦点改变事件处理 spinnertext.setonfocuschangelistener(new Spinner.OnFocusChangeListener(){ ); public void onfocuschange(view v, boolean hasfocus){ v.setvisibility(view.visible); Log.i("spinner","Spinner FocusChange 事件被触发!"); SpinnerActivity 通过 5 个步骤将 Spinner 初始化并进行事件处理, 分别为 : 定义下拉列表的列表项内容 List<String> 为下拉列表 Spinner 定义一个适配器 ArrayAdapter<String>, 并与列表项内容相关联 使用 ArrayAdapter.setDropDownViewResource() 设置 Spinner 下拉列表在打开时的下拉菜单样式 使用 Spinner. setadapter() 将适配器数据与 Spinner 关联起来 为 Spinner 添加事件监听器, 进行事件处理 Spinner 支持多种事件处理方式, 本实例中对 Spinner 被单击事件 焦点改变事件和 Spinner 的列表项被选中事件进行了处理 在本实例中,SpinnerActivity 在程序代码中动态建立了下拉列表每一项的内容 除此之外, 还可以在 XML 文件中定义 Spinner 的下拉列表项, 步骤如下 在 res/values 文件夹下新建 cities.xml 文件夹 :

32 第 4 章 Android GUI 开发 87 <?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="city"> <item>shenyang</item> <item>nanjing</item> <item>beijing</item> <item>tianjin</item> </string-array> </resources> 在 SpinnerActivity.java 中初始化 Spinner: Spinner spinner=(spinner)findviewbyid(r.id.spinner1); ArrayAdapter<CharSequence>adapter=ArrayAdapter.createF romresource(this, R.array.city, android.r.layout.simple_spinner_item); adapter.setdropdownviewresource (android.r.layout.simple_spinner_dropdown_item); spinner.setadapter(adapter); 运行效果如图 4.22 所示 自动完成文本 图 4.22 Spinner 的事件处理 在使用百度或者 Google 搜索信息时, 只需要在搜索框中输入几个关键字, 就会有很多相关的 信息以列表形式被列举出来供用户选择, 这种效果在 Android SDK 中可以通过 AutoCompleteTextView 来实现 下面用一个简单的实例讲解 AutoCompleteTextView 的使用方法 在工程 WidgetDemo 的布局 文件 main.xml 中添加一个 Button, 用以启动 AutoCompleteTextViewActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button5" android:text="autocompletetextviewdemo" /> 单击 Button 并启动 AutoCompleteTextViewActivity 的代码如下 : Button autobtn=(button)this.findviewbyid(r.id.button5); autobtn.setonclicklistener(new OnClickListener(){ public void onclick(view v){ Intent intent=new Intent (WidgetDemoActivity.this,AutoCompleteTextViewActivity.class); ); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name=" AutoCompleteTextViewActivity"></activity>

33 88 Android 7 应用程序开发教程 AutoCompleteTextViewActivity 的运行效果如图 4.23 所示 图 4.23 AutoCompleteTextViewActivity 的运行效果 AutoCompleteTextViewActivity 使用的布局文件为 autocompletetextview.xml, 其具体内容如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:text="autocompletetextview 演示 :" /> <AutoCompleteTextView android:id="@+id/autocompletetextview1" android:layout_width="match_parent" android:text=""> <requestfocus /> </AutoCompleteTextView> </LinearLayout> AutoCompleteTextViewActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; import android.widget.arrayadapter; import android.widget.autocompletetextview; public class AutoCompleteTextViewActivity extends Activity { private AutoCompleteTextView textview;

34 第 4 章 Android GUI 开发 89 Android"; private static final String[] autotext=new String[] {"hello","hello World","hello public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.autocompletetextview); textview=(autocompletetextview )findviewbyid(r.id.autocompletetextview1); /*new ArrayAdapterd 对象将 autotext 字符串数组传入 */ ArrayAdapter<String>adapter=new ArrayAdapter<String> (this,android.r.layout.simple_dropdown_item_1line,autotext); /* 将 ArrayAdapter 添加到 AutoCompleteTextView 中 */ textview.setadapter(adapter); AutoCompleteTextViewActivity 中为可自动补全的内容建立对应字符串数组 autotext, 将该数组关联到 ArrayAdapter 中, 然后将 ArrayAdapter 与 AutoCompleteTextView 相关联, 进而实现自动完成文本功能 AutoCompleteTextView 提供一系列属性对显示效果进行设置, 分别说明如下 completionthreshold: 它的值决定了你在 AutoCompleteTextView 中至少输入几个字符, 才会具有自动提示的功能 另外, 默认最多提示 20 条 dropdownanchor: 它的值是一个 View 的 ID, 指定后,AutoCompleteTextView 会在这个 View 下弹出自动提示 dropdownselector: 应该是设置自动提示的背景色之类的, 没有尝试过, 有待进一步考证 dropdownwidth: 设置自动提示列表的宽度 日期选择器和时间选择器 Android SDK 提供了 DatePicker 和 TimePicker 组件, 分别对日期和时间进行选择, 方便日期和时间设定 下面用一个简单的实例讲解 DatePicker 和 TimePicker 组件的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 Date/Time 的 Button, 用以启动 TimeActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button6" android:text=" Date/Time " /> 单击 Button 并启动 TimeActivity 的代码如下 : Button timebtn=(button)this.findviewbyid(r.id.button6); timebtn.setonclicklistener(new OnClickListener(){ public void onclick(view v){ Intent intent=new Intent(WidgetDemoActivity.this,TimeActivity.class);

35 90 Android 7 应用程序开发教程 ); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name=" TimeActivity"></activity> TimeActivity 的运行效果如图 4.24 所示 图 4.24 TimeActivity 的运行效果 TimeActivity 使用的布局文件为 time.xml, 其内容如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/timeview" android:layout_width="fill_parent" android:text="datepicker 和 TimePicker 演示 " /> <TimePicker android:id="@+id/timepicker" android:layout_height="116dp" android:background="#778888" /> <!-- 设置背景色为墨绿 --> <DatePicker android:id="@+id/datepicker" android:layout_width="271dp" android:layout_height="196dp" android:background="#778899" /> </LinearLayout>

36 第 4 章 Android GUI 开发 91 TimeActivity.java 的代码如下 : package introduction.android.widgetdemo; import java.util.calendar; import android.app.activity; import android.os.bundle; import android.widget.datepicker; import android.widget.textview; import android.widget.timepicker; public class TimeActivity extends Activity { private TextView textview; private TimePicker timepicker; private DatePicker datepicker; /* 声明日期及时间变量 */ private int year; private int month; private int day; private int hour; private int minute; public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.time); /* 获取当前日期及时间 */ Calendar calendar=calendar.getinstance(); year=calendar.get(calendar.year); month=calendar.get(calendar.month); day=calendar.get(calendar.day_of_month); hour=calendar.get(calendar.hour); minute=calendar.get(calendar.minute); datepicker=(datepicker)findviewbyid(r.id.datepicker); timepicker=(timepicker)findviewbyid(r.id.timepicker); /* 设置 TextView 对象, 显示初始日期时间 */ textview=(textview)findviewbyid(r.id.timeview); textview.settext(new StringBuilder().append(year).append("/").append(format(month+1)).append("/").append(format(day)).append(" ").append(format(hour)).append(":").append(format(minute))); /* 设置 OnDateChangedListener()*/ datepicker.init(year, month, day, new DatePicker.OnDateChangedListener(){ public void ondatechanged(datepicker view, int year, int monthofyear, int dayofmonth){ TimeActivity.this.year=year; month=monthofyear; day=dayofmonth; textview.settext(new StringBuilder().append(year).append("/").append(format(month+1)).append("/").append(format(day)).append(" ")

37 92 Android 7 应用程序开发教程.append(format(hour)).append(":").append(format(minute))); ); timepicker.setontimechangedlistener(new TimePicker.OnTimeChangedListener() { public void ontimechanged(timepicker view, int hourofday, int minute) { ); hour=hourofday; TimeActivity.this.minute=minute; textview.settext(new StringBuilder().append(year).append("/").append(format(month+1)).append("/").append(format(day)).append(" ").append(format(hour)).append(":").append(format(minute))); private String format(int time){ String str=""+time; if(str.length()==1) str="0"+str; return str; TimeActivity 中使用 java.util.calendar 对象获取当前系统时间 当更改 DatePicker 组件中的日期时, 会触发 DatePicker 的 OnDateChange() 事件 ; 当修改 TimePacker 的时间时, 会触发 TimePacker 的 OnDateChange() 事件 由本实例可见,DatePicker 实现 OnDateChangedListener 监听器的方法与 TimePicker 实现 setontimechangedlistener 监听器的方法有所类似 DatePicker 用 init() 方法设定年 月 日的同时设定监听器, 而 TimePicker 使用 setontimechangedlistener() 直接设定 进度条 当应用程序在后台运行时, 可以使用进度条 (ProgressBar) 反馈给用户当前的进度信息 进度条被用以显示当前应用程序的运行状况 功能完成多少等情况 Android SDK 提供两种样式的进度条, 一种是圆形的进度条, 另一种是水平进度条 其中圆形进度条分大 中 小三种 进度条本质上是一个整数, 显示当前的整数值在特定范围内的比重 下面用一个简单的实例讲解 ProgressBar 组件的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 ProgressBarDemo 的 Button, 用以启动 ProcessBarActivity 在 main.xml 中添加代码如下 :

38 第 4 章 Android GUI 开发 93 <Button android:id="@+id/button7" android:text="progressbardemo" /> 单击 Button 并启动 ProcessBarActivity 的代码如下 : Button processbtn=(button)this.findviewbyid(r.id.button7); processbtn.setonclicklistener(new OnClickListener(){ public void onclick(view v){ Intent intent=new Intent (WidgetDemoActivity.this,ProcessBarActivity.class); ); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name="processbaractivity"></activity> ProcessBarActivity 的运行效果如图 4.25 所示 图 4.25 ProcessBarActivity 的运行效果 ProcessBarActivity 使用的布局文件为 processbar.xml, 其内容如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ProgressBar android:id="@+id/progressbar1" style="?android:attr/progressbarstylesmall" />

39 94 Android 7 应用程序开发教程 <ProgressBar android:id="@+id/progressbar2" /> <ProgressBar android:id="@+id/progressbar3" style="?android:attr/progressbarstylelarge" /> <ProgressBar android:id="@+id/progressbar4" style="?android:attr/progressbarstylehorizontal" android:layout_width="209dp" android:layout_height="30dp" android:max="100"/> </LinearLayout> 该布局中放置了小 中 大三种类型的圆形进度条各一个, 以及一个水平放置的条形进度条 一般情况下, 开发人员不会为圆形进度条指定进度, 圆形进度条只是展示运行效果, 而不反映实际的进度 条形进度条则不同, 开发人员会为条形进度条指定最大值, 以及进度条当前值的获取方法 在本实例中, 条形进度条的最大值为 100 ProcessBarActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; import android.os.handler; import android.widget.progressbar; public class ProcessBarActivity extends Activity { ProgressBar progressbar; int i=0; int progressbarmax=0; /* 创建 Handler 对象 */ Handler handler=new Handler(); public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.processbar); progressbar=(progressbar)findviewbyid(r.id.progressbar4); /* 获取最大值 */ progressbarmax=progressbar.getmax(); /* 匿名内部类启动实现效果的线程 */ new Thread(new Runnable(){ public void run(){ while(i++<progressbarmax){

40 第 4 章 Android GUI 开发 95 // 设置滚动条当前状态值 progressbar.setprogress(i); try { Thread.sleep(15); ).start(); catch(exception e){ e.printstacktrace(); ProcessBarActivity 对水平进度条进行了处理 先获取了水平进度条的最大值, 然后启动了一个线程, 由该线程来控制进度条的值, 从 0 开始, 每隔 15 毫秒增加 滚动视图 当 Activity 提供的用户界面上有很多内容, 以至于当前手机屏幕不能完全显示全部内容时, 就需要滚动视图来帮助浏览全部的内容 以工程 WidgetDemo 为例, 由于在讲述过程中不断地在 main.xml 文件中添加按钮和其他组件, 目前已经不能显示全部内容, 效果如图 4.26 所示 图 4.26 添加大量组件后的效果这时候就需要使用 ScrollView, 即将当前的 Activity 的视图转化为滚动视图, 以便于浏览 ScrollView 的使用非常方便, 只需在 main.xml 的 <LinearLayout> 标签外面加上 ScrollView 组件的声明即可 布局文件 main.xml 的内容如下 : <ScrollView xmlns:android="

41 96 Android 7 应用程序开发教程 android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout>...</LinearLayout> </ScrollView> 添加 ScrollView 后,main.xml 布局的运行效果如图 4.27 所示 图 4.27 ScrollView 的运行效果 拖动条 SeekBar 是水平进度条 ProgressBar 的间接子类, 相当于一个可以拖动的水平进度条 下面仍以一个简单的实例讲解 SeekBar 组件的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 SeekBarDemo 的 Button, 用以启动 SeekBarActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button8" android:text="seekbardemo" /> 单击 Button 并启动 SeekBarActivity 的代码如下 : Button processbtn=(button)this.findviewbyid(r.id.button8); processbtn.setonclicklistener(new OnClickListener(){ ); public void onclick(view v){ Intent intent=new Intent(WidgetDemoActivity.this, SeekBarActivity.class); startactivity(intent);

42 第 4 章 Android GUI 开发 97 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name="seekbaractivity"></activity> SeekBarActivity 的运行效果如图 4.28 所示 图 4.28 SeekBarActivity 的运行效果 SeekBarActivity 使用的布局文件为 seekbar.xml, 其内容如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/textview1" android:text="textview" /> <SeekBar android:id="@+id/seekbar1" android:layout_width="match_parent" android:max="100"/> </LinearLayout> 该文件确定 SeekBar 对象的最大值为 100, 宽度为手机屏幕的宽度 SeekBarActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity;

43 98 Android 7 应用程序开发教程 import android.os.bundle; import android.util.log; import android.widget.seekbar; import android.widget.textview; public class SeekBarActivity extends Activity { private TextView textview; private SeekBar seekbar; public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.seekbar); textview=(textview)findviewbyid(r.id.textview1); seekbar=(seekbar)findviewbyid(r.id.seekbar1); /* 设置 SeekBar 监听 setonseekbarchangelistener */ seekbar.setonseekbarchangelistener(new SeekBar.OnSeekBarChangeListener(){ /* 拖动条停止拖动时调用 */ ); public void onstoptrackingtouch(seekbar seekbar){ Log.i("SeekBarActivity", " 拖动停止 "); /* 拖动条开始拖动时调用 */ public void onstarttrackingtouch(seekbar seekbar){ Log.i("SeekBarActivity", " 开始拖动 "); /* 拖动条进度改变时调用 */ public void onprogresschanged(seekbar seekbar, int progress, boolean fromuser){ textview.settext(" 当前进度为 :"+progress+"%"); SeekBar 的事件处理接口为 OnSeekBarChangeListener, 该监听器提供对三种事件的监听, 分别为当 SeekBar 的拖动条开始被拖动时 拖动条拖动停止时和拖动条的位置发生改变时 SeekBarActivity 在拖动条开始被拖动和拖动停止时, 会通过 Logcat 打印相关信息 当拖动条位置发生改变时, 将当前的数值显示到 TextView 中 评价条 在网上购物的时候, 经常会对所购买的商品进行打分 一般对商品的评价和打分是以 5 个星星的方式进行的 Android SDK 提供了 RatingBar 组件来实现该功能 RatingBar 是 SeekBar 和 ProgressBar 的扩展, 是 ProgressBar 的间接子类, 可以使用 ProgressBar 相关的属性 RatingBar 有三种风格, 分别为默认风格 (ratingbarstyle) 小风格(ratingBarStyleSmall) 和大风格 (ratingbarstyleindicator ) 其中, 默认风格的 RatingBar 是我们通常使用的, 可以进行交互, 而其他两种不能进行交互

44 第 4 章 Android GUI 开发 99 以一个简单的实例讲解 RatingBar 组件的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 RatingBarDemo 的 Button, 用以启动 RatingBarActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button9" android:text="ratingbardemo" /> 单击 Button 并启动 RatingBarActivity 的代码如下 : Button ratingbarbtn=(button)this.findviewbyid(r.id.button9); ratingbarbtn.setonclicklistener(new OnClickListener(){ ); public void onclick(view v){ Intent intent=new Intent(WidgetDemoActivity.this,RatingBarActivity.class); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name="ratingbaractivity"></activity> RatingBarActivity 的运行效果如图 4.29 所示 图 4.29 RatingBarActivity 的运行效果 RatingBarActivity 使用的布局文件 ratingbar.xml 的内容如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">

45 100 Android 7 应用程序开发教程 <TextView android:id="@+id/textview1" android:text="textview" /> <RatingBar android:id="@+id/ratingbar1" android:numstars="5" android:stepsize="0.5" android:rating="3"/> </LinearLayout> 该布局文件使用 LinearLayout 布局, 其中放置了一个 TextView 和一个 RatingBar, 并对 RatingBar 的相关属性进行了设置 android:numstars="5" 用于设置 RatingBar 显示的星星数量为 5 个 ;android:stepsize="0.5" 用于设置 RatingBar 的最小变化单位为半个星星 ;android:rating ="3" 表示 RatingBar 在初始状态下被选中的星星数量为 3 个 RatingBarActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; import android.util.log; import android.view.motionevent; import android.view.view; import android.view.view.ontouchlistener; import android.widget.ratingbar; import android.widget.ratingbar.onratingbarchangelistener; import android.widget.textview; import android.widget.toast; public class RatingBarActivity extends Activity { private RatingBar chooseratingbar; private TextView textview; public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.ratingbar); textview=(textview)findviewbyid(r.id.textview1); chooseratingbar=(ratingbar)findviewbyid(r.id.ratingbar1); /* 创建 RatingBar 监听器 */ chooseratingbar.setonratingbarchangelistener(new OnRatingBarChangeListener(){ { public void onratingchanged(ratingbar ratingbar,float rating, boolean fromuser) chooseratingbar=(ratingbar)findviewbyid(r.id.ratingbar1);

46 第 4 章 Android GUI 开发 101 ); chooseratingbar.setrating(rating); textview.settext(" 您选择了 "+rating+" 个星星 "); RatingBarActivity 为 RatingBar 对象设置了 OnRatingBarChangeListener 监听器, 当用户单击 RatingBar 引起被选中星星数量的变化时, 该接口会监测到该事件, 并且调用 onratingchanged() 方法, 更新 TextView 显示的内容 onratingchanged() 的三个参数所对应的含义如下 ratingbar: 多个 RatingBar 可以同时指定同一个 RatingBar 监听器 该参数就是当前触发 RatingBar 监听器的那个 RatingBar 对象 rating: 当前评级分数 取值范围从 0 到 RatingBar 的总星星数 fromuser: 如果触发监听器的是用户触屏单击或轨迹球左右移动, 则为 true 图片视图和图片按钮 ImageView 是用于显示图片的组件, 在很多场合都有比较普遍的使用 ImageView 可以显示任意图像, 加载各种来源的图片 ( 如资源或图片库 ) ImageView 可以负责计算图片的尺寸, 以便在任意的布局中使用, 并且可以提供缩放或者着色等选项供开发者使用 ImageButton 是 ImageView 的子类, 相当于一个表明是图片而不是文字的 Button 其使用方法和 Button 完全相同 下面通过一个实例来了解一下这两个组件的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 ImageButtonDemo 的 Button, 用以启动 ImageButtonActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button10" android:text="imagebuttondemo" /> 单击 Button 并启动 RatingBarActivity 的代码如下 : Button imgbtn=(button)this.findviewbyid(r.id.button10); imgbtn.setonclicklistener(new OnClickListener(){ ); public void onclick(view v){ Intent intent=new Intent(WidgetDemoActivity.this,ImageButtonActivity.class); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name="imagebuttonactivity"></activity>

47 102 Android 7 应用程序开发教程 ImageButtonActivity 的运行效果如图 4.30 所示 图 4.30 ImageButtonActivity 的运行效果 ImageButtonActivity 的布局文件 imgbtn.xml 内容如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/imageview1" android:layout_width="250dp" android:layout_height="250dp" android:src="@drawable/girl" /> <ImageButton android:id="@+id/imagebutton1" android:src="@drawable/ic_launcher" /> </LinearLayout> 该文件使用 LinearLayout 布局, 其中放入了一个 ImageView 组件和一个 ImageButton 组件 两个组件都通过 android:src 属性指定了显示的图片 该实例用到了两个图片资源, 一个为 girl, 另一个为 ic_launcher, 如图 4.31 所示 由于 Android 会根据手机设备的配置高低选择不同的资源, 因此为了应用程序的通用性, 在三个 drawable 文件夹下都放置了 girl.gif 图像 ic_launcher.png 是系统自带的资源文件

48 第 4 章 Android GUI 开发 103 ImageButtonActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; 图 4.31 工程中的图片资源 import android.view.view; import android.view.viewgroup.layoutparams; import android.widget.imagebutton; import android.widget.imageview; public class ImageButtonActivity extends Activity { private ImageButton imgbtn; private ImageView imgview; protected void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.imgbtn); imgbtn=(imagebutton)this.findviewbyid(r.id.imagebutton1); imgview=(imageview)this.findviewbyid(r.id.imageview1); imgbtn.setonclicklistener(new View.OnClickListener(){ ); public void onclick(view v){ LayoutParams params=imgview.getlayoutparams(); params.height+=3; params.width+=3; imgview.setlayoutparams(params); ImageButtonActivity 为 ImageButton 添加了单击监听器, 对用户单击 imgbtn 的事件进行了处理 用户每次单击图片按钮, 都把 ImageView 组件的宽和高增大 3 随着用户的不断单击,ImageView 中显示的图片越来越大, 显示了 ImageView 组件对图片的缩放功能

49 104 Android 7 应用程序开发教程 图片切换器和图库 在使用 Android 手机设置壁纸的时候, 会看到屏幕底部有很多可以滚动的图片, 当单击某一图片时, 在其上面的空间会显示当前选中的图片, 此时我们用到的就是 Gallery( 图库 ) 和 ImageSwitcher ( 图片切换器 ) Gallery 组件用于横向显示图像列表, 并且自动将当前图像放置到中间位置 ImageSwitcher 则像是图片浏览器, 可以切换图片, 通过它可以制作简单的幻灯片等 通常将这两个类结合在一起使用, 可以制作有一定效果的相册 下面通过一个实例来了解一下这两个组件的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 GalleryDemo 的 Button, 用以启动 GalleryActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button11" android:text="gallerydemo" /> 单击 Button 并启动 GalleryActivity 的代码如下 : Button gallerybtn=(button)this.findviewbyid (R.id.button11); gallerybtn.setonclicklistener(new OnClickListener(){ public void onclick(view v){ Intent intent=new Intent (WidgetDemoActivity.this,GalleryActivity.class); startactivity(intent); ); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name="galleryactivity"></activity> GalleryActivity 的运行效果如图 4.32 所示 GalleryActivity 使用的布局文件为 gallery.xml, 内容如下 : 图 4.32 GalleryActivity 的运行效果 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <ImageSwitcher android:id="@+id/switcher" android:layout_width="match_parent" android:layout_height="match_parent"

50 第 4 章 Android GUI 开发 105 android:layout_alignparenttop="true" android:layout_alignparentleft="true"> </ImageSwitcher> <Gallery android:id="@+id/gallery" android:background="#333333" android:layout_width="fill_parent" android:layout_height="60dp" android:layout_alignparentbottom="true" android:layout_alignparentleft="true" android:gravity="center_vertical" android:spacing="16dp" /> </RelativeLayout> 该布局文件使用的是相对布局, 通过 android:layout_alignparenttop="true" 属性将 ImageSwitcher 放置于视图的顶端, 其顶部与其父组件的顶部对齐, 同时使用 android: layout_alignparentleft="true" 属性使 ImageSwitcher 的左边缘与其父组件的左边缘对齐 在设置 Gallery 组件时, 将其与屏幕的左下角对其,android:layout_alignParentBottom="true" 是将该组件的底部与其父组件的底部对齐, 并且使用 android:spacing="16dp" 属性设置图片之间的间距 GalleryActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.content.context; import android.os.bundle; import android.view.view; import android.view.viewgroup; import android.view.viewgroup.layoutparams; import android.view.animation.animationutils; import android.widget.adapterview; import android.widget.adapterview.onitemselectedlistener; import android.widget.baseadapter; import android.widget.gallery; import android.widget.imageswitcher; import android.widget.imageview; import android.widget.viewswitcher.viewfactory; public class GalleryActivity extends Activity { private Gallery gallery; private ImageSwitcher imageswitcher; private int[] resids=new int[] { R.drawable.sample_0, R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5, R.drawable.sample_6, R.drawable.sample_7; public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.gallery); /* 加载 Gallery 和 ImageSwitcher */ gallery=(gallery)findviewbyid(r.id.gallery); imageswitcher=(imageswitcher)findviewbyid(r.id.switcher);

51 106 Android 7 应用程序开发教程 /* 创建用于描述图像数据的 ImageAdapter 对象 */ ImageAdapter imageadapter=new ImageAdapter(this); /* 设置 Gallery 组件的 Adapter 对象 */ gallery.setadapter(imageadapter); /* 添加 Gallery 监听器 */ gallery.setonitemselectedlistener(new OnItemSelectedListener(){ public void onitemselected(adapterview<?>parent, View view, int position, long id){ // 当选取 Grallery 上的图片时, 在 ImageSwitcher 组件中显示该图像 imageswitcher.setimageresource(resids[position]); public void onnothingselected(adapterview<?>arg0){ ); /* 设置 ImageSwitcher 组件的工厂对象 */ imageswitcher.setfactory(new ViewFactory(){ /* ImageSwitcher 用这个方法来创建一个 View 对象去显示图片 */ public View makeview(){ ImageView imageview=new ImageView(GalleryActivity.this); /* setscaletype 可以设置当图片大小和容器大小不匹配时的剪辑模式 */ imageview.setscaletype(imageview.scaletype.fit_center); imageview.setlayoutparams(new ImageSwitcher.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); return imageview; ); /* 设置 ImageSwitcher 组件显示图像的动画效果 */ imageswitcher.setinanimation(animationutils.loadanimation(this, android.r.anim.fade_in)); imageswitcher.setoutanimation(animationutils.loadanimation(this, android.r.anim.fade_out)); public class ImageAdapter extends BaseAdapter { /* 定义 Context */ private Context mcontext; /* 声明 ImageAdapter */ public ImageAdapter(Context context){ mcontext=context; /* 获取图片的个数 */ public int getcount(){

52 第 4 章 Android GUI 开发 107 return resids.length; /* 获取图片在库中的位置 */ public Object getitem(int position){ return position; /* 获取图片 ID */ public long getitemid(int position){ return position; /* 返回具体位置的 ImageView 对象 */ public View getview(int position, View convertview, ViewGroup parent){ ImageView imageview=new ImageView(mContext); /* 给 ImageView 设置资源 */ imageview.setimageresource(resids[position]); /* 设置图片布局大小为 100*100 */ imageview.setlayoutparams(new Gallery.LayoutParams(100, 100)); /* 设置显示比例类型 */ imageview.setscaletype(imageview.scaletype.fit_xy); return imageview; Gallery 要显示的图片来自资源文件 把需要显示的图片放在 /res/drawable 目录下后, 将这些图片的 ID 保存在一个 int 数组中以备使用 相关代码如下 : private int[] resids=new int[] { R.drawable.sample_0, R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5, R.drawable.sample_6, R.drawable.sample_7; Gallery 通过 setadapter(imageadapter) 方法将组件和要显示的图片关联起来 本实例中为 Gallery 设定的适配器为 ImageAdapter, 主要用于描述图像信息, 其为 android.widget.baseadapter 的子类 在 ImageAdapter 类中有两个方法值得我们注意, 其中一个是 getcount() 方法, 它用于返回图片的总数, 通常使用获取存放图片数组长度的方法获取图片总数, 也可以规定具体的返回数, 但不能超过实际图片数量 ;getview() 方法是当 Gallery 中需要显示某一个图像时, 将当前图片的索引, 也就是 position 的值传入, 从 resids 数组中获得相应的图片的 ID GalleryActivity 为添加 Gallery 监听器, 处理了用户单击 Gallery 中图片的事件, 并设置了 ImageSwitcher 相关属性 其代码如下 :

53 108 Android 7 应用程序开发教程 imageswitcher.setinanimation(animationutils.loadanimation(this, android.r.anim.fade_in)); imageswitcher.setoutanimation(animationutils.loadanimation(this, android.r.anim.fade_out)); 设置了 ImageSwitcher 组件图片切换时的渐入和渐出效果 网格视图 GridView 提供了一个二维的可滚动的网格, 按照行列的方式来显示内容, 一般适合显示图标 图片等, 适合浏览 下面通过一个实例来了解一下 GridView 组件的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 GridViewDemo 的 Button, 用以启动 GridViewActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button12" android:text="gridviewdemo" /> 单击 Button 并启动 GridViewActivity 的代码如下 : Button gridviewbtn=(button)this.findviewbyid (R.id.button12); gridviewbtn.setonclicklistener(new OnClickListener(){ public void onclick(view v){ Intent intent=new Intent (WidgetDemoActivity.this,GridViewActivity.class); ); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name="gridviewactivity"> </activity> GridViewActivity 的运行效果如图 4.33 所示 GridViewActivity 使用的布局文件为 gridview.xml, 其内容如下 : 图 4.33 GridViewActivity 的运行效果 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <GridView

54 第 4 章 Android GUI 开发 109 android:id="@+id/gridview1" android:layout_width="match_parent" android:numcolumns="3"> </GridView> </LinearLayout> 该视图采用 LinearLayout 的布局方式, 其中放置了一个 GridView 组件, 该组件由三列组成 GridViewActivity.java 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.content.context; import android.os.bundle; import android.util.log; import android.view.view; import android.view.viewgroup; import android.widget.adapterview; import android.widget.adapterview.onitemclicklistener; import android.widget.baseadapter; import android.widget.gridview; import android.widget.imageview; public class GridViewActivity extends Activity { public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.gridview); GridView gridview=(gridview)findviewbyid(r.id.gridview1); gridview.setadapter(new ImageAdapter(this)); gridview.setonitemclicklistener(new OnItemClickListener(){ ); public void onitemclick(adapterview<?>parent, View v, int position, long id){ Log.i("gridview", " 这是第 "+position+" 幅图像 "); public class ImageAdapter extends BaseAdapter { private Context mcontext; public ImageAdapter(Context c){ mcontext=c; /* 获取当前图片数量 */ public int getcount(){ return mthumbids.length; /* 根据需要 position 获得在 GridView 中的对象 */

55 110 Android 7 应用程序开发教程 public Object getitem(int position){ return position; /* 获得在 GridView 中对象的 ID */ public long getitemid(int id){ return id; public View getview(int position, View convertview, ViewGroup parent){ ImageView imageview; if(convertview==null){ /* 实例化 ImageView 对象 */ imageview=new ImageView(mContext); /* 设置 ImageView 对象布局, 设置 View 的 height 和 width */ imageview.setlayoutparams(new GridView.LayoutParams(85, 85)); /* 设置边界对齐 */ imageview.setadjustviewbounds(false); /* 按比例统一缩放图片 ( 保持图片的尺寸比例 )*/ imageview.setscaletype(imageview.scaletype.center_crop); /* 设置间距 */ imageview.setpadding(8, 8, 8, 8); else { imageview=(imageview)convertview; imageview.setimageresource(mthumbids[position]); return imageview; // references to our images private Integer[] mthumbids={ R.drawable.sample_2, R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5, R.drawable.sample_6, R.drawable.sample_7, R.drawable.sample_0, R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5, R.drawable.sample_6, R.drawable.sample_7, R.drawable.sample_0, R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5, R.drawable.sample_6, R.drawable.sample_7 ; 在主程序 GridViewActivity 中, 为 GridView 设置了一个数据适配器, 并处理了 GridView 的单击事件 适配器继承自 BaseAdapter 类, 与 节中用到的适配器高度相似, 在此不再重复 标签 在有限的手机屏幕空间内, 当要浏览的内容较多, 无法在一个屏幕空间内全部显示时, 可以使用滚动视图来延长屏幕的空间 当浏览的内容具有很强的类别性质时, 更合适的方法是将不同类别的内容集中到各自的面板中, 这时就需要使用面板标签 (Tab) 组件了

56 第 4 章 Android GUI 开发 111 Tab 组件利用面板标签把不同的面板内容切换到屏幕上, 以显示不同类别的内容 下面通过一个实例来了解一下 Tab 组件的使用方法 在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 TabDemo 的 Button, 用以启动 TabActivity 在 main.xml 中添加代码如下 : <Button android:id="@+id/button13" android:text="tabdemo" /> 单击 Button 并启动 GridViewActivity 的代码如下 : Button tabbtn=(button)this.findviewbyid(r.id.button13); tabbtn.setonclicklistener(new OnClickListener(){ public void onclick(view v){ ); Intent intent=new Intent(WidgetDemoActivity.this,TabActivity.class); startactivity(intent); 同时在 AndroidManifest.xml 文件中声明该 Activity: <activity android:name="tabactivity"></activity> TabActivity 的运行效果如图 4.34 所示 图 4.34 TabActivity 的运行效果要使用 Tab 必然涉及它的容器 TabHost,TabHost 包括 TabWigget 和 FrameLayout 两部分 TabWidget 就是每个 Tab 的标签,FrameLayout 是 Tab 的内容 TabActivity 使用的布局文件是 tab.xml 在 tab.xml 中定义了每个 Tab 中要显示的内容, 代码如下 :

57 112 Android 7 应用程序开发教程 <?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android=" android:id="@+id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/tab1" android:textsize="40dp" android:text="tab1 页面 " /> <TextView android:id="@+id/tab2" android:textsize="40dp" android:text="tab2 页面 " /> <TextView </FrameLayout> </LinearLayout> </TabHost> android:id="@+id/tab3" android:textsize="40dp" android:text="tab3 页面 " /> 在 FrameLayout 中我们放置了三个 TextView 组件, 分别对应三个 Tab 所显示的内容, 当切换不同的 Tab 时会自动显示不同的 TextView 内容 在主程序 TabActivity 的 OnCreate() 方法中, 首先获得 TabHost 的对象, 并调用 setup() 方法进行初始化, 然后通过 TabHost.TabSpec 增加 Tab 页, 通过 setcontent() 增加当前 Tab 页显示的内容, 通过 setindicator 增加页的标签, 最后设定当前要显示的 Tab 页 TabActivity 的代码如下 : package introduction.android.widgetdemo; import android.app.activity; import android.os.bundle; import android.widget.tabhost; public class TabsActivity extends Activity {

58 第 4 章 Android GUI 开发 113 增加页的标签 public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.tab); // 步骤 1: 获得 TabHost 的对象, 并进行初始化 setup() TabHost tabs=(tabhost)findviewbyid(r.id.tabhost); tabs.setup(); // 步骤 2: 通过 TabHost.TabSpec 增加 tab 的一页, 通过 setcontent() 增加内容, 通过 setindicator /* 增加第 1 个 Tab */ TabHost.TabSpec spec=tabs.newtabspec("tag1"); // 单击 Tab 要显示的内容 spec.setcontent(r.id.tab1); /* 显示 Tab1 内容 */ spec.setindicator("tab1"); tabs.addtab(spec); /* 增加第 2 个 Tab */ spec=tabs.newtabspec("tag2"); spec.setcontent(r.id.tab2);// 单击 Tab 要显示的内容 /* 显示 Tab2 内容 */ spec.setindicator("tab2"); tabs.addtab(spec); /* 增加第 3 个 Tab */ spec=tabs.newtabspec("tag3"); spec.setcontent(r.id.tab3);// 单击 Tab 要显示的内容 /* 显示 Tab3 内容 */ spec.setindicator("tab3"); tabs.addtab(spec); /* 步骤 3: 可通过 setcurrenttab(index) 指定显示的页, 从 0 开始计算 */ tabs.setcurrenttab(0); 除了使用上述方法设置 Tab 页面的显示内容外, 还可以使用 setcontent(intent) 方法启动某个 Activity, 并将该 Activity 的视图作为 Tab 页面的内容 例如 : Intent intent=new Intent().setClass(this, AlbumsActivity.class); spec=tabhost.newtabspec("albums").setindicator("albums", tabhost.addtab(spec); res.getdrawable(r.drawable.ic_tab_albums)).setcontent(intent); 4.5 Menu 和 ActionBar 菜单是人机交互的重要接口, 在 Android SDK 中, 提供了菜单类 android.view.menu, 以完成与菜单有关的操作 Android SDK 提供三种菜单, 分别如下 Options Menu: 选项菜单, 是 Activity 的主要菜单项的集合, 当用户单击 Menu 按钮时出现

59 114 Android 7 应用程序开发教程 在 Android 2.3 以下的版本中, 这种菜单最多显示 6 个带图标的菜单项 当菜单中含有 6 个以上的菜单项时, 弹出菜单将只显示前 5 个菜单项, 第 6 个菜单项会变为 More, 单击 More 菜单项后会出现扩展菜单 扩展菜单不支持图标, 但支持单选框和复选框 在 Android 3.0(API Level 11) 及以上版本中, 默认情况下直接弹出的选项菜单不再显示图标 Context Menu: 上下文菜单, 是一个悬浮的菜单项列表, 当用户单击注册了上下文菜单的组件时出现 上下文菜单不支持菜单图标和快捷键 Submenu: 子菜单, 是某个菜单项的扩展, 是一个悬浮的菜单项列表 子菜单不支持菜单图标或者嵌套子菜单 Options Menu 要实现选项菜单的功能, 首先需要重载 OnCreatOptionsMenu() 方法创建菜单, 然后通过 onoptionsitemselected() 方法对菜单被单击事件进行监听和处理 创建一个名为 MenusDemo 的 Android Project, 在该工程中对菜单的相关知识进行学习 在工程的 res 目录下创建一个 menu 目录, 用于存放菜单相关的 XML 文件 在该目录下创建 mymenu.xml, 代码如下 : <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android=" <item android:id="@+id/item1" android:title="@string/menuitem1" android:icon="@drawable/icon01"/> <item <item android:id="@+id/item2" android:title="@string/menuitem2" android:icon="@drawable/icon02"/> android:id="@+id/item3" android:title="@string/menuitem3" android:icon="@drawable/icon03"/> <item android:id="@+id/item4" android:title="@string/menuitem4" android:icon="@drawable/icon04"/> <item <item android:id="@+id/item5" android:title="@string/menuitem5" android:icon="@drawable/icon05"/> android:id="@+id/item6" android:title="@string/menuitem6" android:icon="@drawable/icon06"/> <item android:id="@+id/item7" android:title="@string/menuitem7" android:icon="@drawable/icon07"/> </menu>

60 第 4 章 Android GUI 开发 115 mymenu.xml 创建了一个具有 7 个菜单项的菜单, 并且通过 android:id 属性为每个菜单项指定 ID, 通过 android:title 属性为每个菜单项指定显示的菜单项内容, 通过 android:icon 属性指定每个菜单项的图标 对应的图标文件放置到 res/drawable 目录下 为工程 MenusDemo 创建名为 MenusActivity 的 Activity, 将 mymenu.xml 中定义的菜单设置为 MenusActivity 的菜单, 重载 OnCreatOptionsMenu() 方法 MenusActivity.java 的代码如下 : package introduction.android.menusdemo; import android.app.actionbar; import android.app.activity; import android.os.bundle; import android.view.menu; import android.view.menuinflater; import android.view.menuitem; import android.view.view; import android.widget.textview; public class MenusDemoActivity extends Activity { private TextView textview; /** Called when the activity is first created. */ public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.main); textview=(textview)findviewbyid(r.id.textview1); public boolean onoptionsitemselected(menuitem item){ switch(item.getitemid()){ case R.id.item1: textview.settext("item1 selected!"); break; case R.id.item2: textview.settext("item2 selected!"); break; case R.id.item3: textview.settext("item3 selected!"); break; default: break; return super.onoptionsitemselected(item); public boolean oncreateoptionsmenu(menu menu){ MenuInflater inflater=getmenuinflater(); 其中 : inflater.inflate(r.menu.mymenu, menu); return true;

61 116 Android 7 应用程序开发教程 public boolean oncreateoptionsmenu(menu menu){ MenuInflater inflater=getmenuinflater(); inflater.inflate(r.menu.mymenu, menu); return true; 这几行代码通过 MenuInflater. Inflate() 方法将 menu.xml 中定义的菜单项内容填充到了菜单中 在 OnCreatOptionsMenu() 方法中创建菜单时也支持 Menu.add() 方法, 也能达到同样目的, 例如 : menu.add(0,itemid,0,item_title); 表示在菜单中添加一个菜单项, 该菜单项的 ID 为 itemid, 菜单项显示的内容为 item_title 的内容 但是不鼓励使用这种方式, 而应该使用 XML 文件来创建菜单 运行 MenusDemo 实例, 单击手机的 Menu 按钮, 得到的效果如图 4.35 所示 由运行效果可见,MenusActivity 已经根据 mymenu.xml 文件创建了一个具有 7 个菜单项的菜单 但是虽然在 mymenu.xml 文件中为每个菜单项指定了一个图标, 但是生成的选项菜单中却并没有图标被显示出来, 这是为什么呢? 实例 MenusDemo 当前的运行环境是 Android 4.0, 其 API Level 为 14 我们先看一下, 同样的代码, 在 API Level 11 之前的运行效果 双击打开 AndroidManifest.xml 文件, 将其中的代码 : 改为 : <uses-sdk android:minsdkversion="14" /> <uses-sdk android:minsdkversion="9" /> 再次运行 MenusDemo 实例, 单击 Menu 按钮, 得到的效果如图 4.36 所示 图 4.35 Menu 按钮运行效果 图 4.36 API Level 11 之前 Menu 按钮的运行效果 可见运行在早期的 API 之上的选项菜单效果要更好一些 为什么会出现这种现象呢? 其实在 Android SDK 3.0 之后, 就不再鼓励直接使用选项菜单, 而是将选项菜单和 ActionBar 结合使用

62 第 4 章 Android GUI 开发 117 ActionBar 又称活动栏, 位于 Activity 的顶部, 取代了原来标题的位置 ActionBar 中包含很多 ActionItem, 相当于选项菜单的菜单项 将选项菜单与 ActionBar 结合的方法很简单, 只要在 XML 文件中添加一个 android:showasaction="ifroom" 属性即可 该属性表现如果标题栏有空间的话, 就将相关的菜单项放置到 ActionBar 中 如果标题栏空间不足, 未能放置到其中的菜单项仍然会以选项菜单的形式出现 ActionBar 的运行效果如图 4.37 所示 Context Menu 上下文菜单注册到 View 对象上后, 用户长按该 View 对象可呼出上下文菜单 上下文菜单悬浮于主界面之上, 不支持图标显示和快捷键 其使用方法和选项菜单高度相似, 只不过创图 4.37 ActionBar 的运行效果建上下文菜单的方法为 oncreatecontextmenu(), 响应上下文菜单单击事件的方法为 oncontextitemselected() 仍以工程 MenusDemo 为例, 为 MenusActivity 的视图中的 TextView 对象添加一个具有两个菜单项的上下文菜单, 运行效果如图 4.38 所示 图 4.38 两个上下文菜单的运行结果 为 TextView 对象注册上下文菜单的代码如下 : textview=(textview)findviewbyid(r.id.textview1); registerforcontextmenu(textview); 创建并处理上下文菜单单击事件的代码如下 : public boolean oncontextitemselected(menuitem item){

63 118 Android 7 应用程序开发教程 switch(item.getitemid()){ case R.id.item6: Log.i("menu","item6!"); break; case R.id.item7: default: Log.i("menu","item7!"); break; break; return super.oncontextitemselected(item); public void oncreatecontextmenu(contextmenu menu, View v, ContextMenuInfo menuinfo){ menu.add(0, R.id.item6, 0, " 上下文菜单项一 "); menu.add(0, R.id.item7, 0, " 上下文菜单项二 "); super.oncreatecontextmenu(menu, v, menuinfo); SubMenu 子菜单可以被添加到其他菜单上, 但是子菜单本身不能再有子菜单 使用 addsubmenu() 方法为 MenusActivity 的选项菜单添加一个子菜单, 运行效果如图 4.39 所示 图 4.39 添加子菜单的运行效果 实现该子菜单需要重写 oncreateoptionsmenu() 方法, 代码如下 : public boolean oncreateoptionsmenu(menu menu){ MenuInflater inflater=getmenuinflater(); inflater.inflate(r.menu.mymenu, menu); SubMenu submenu=menu.addsubmenu(" 子菜单 "); submenu.add(0,1,0," 子菜单项一 ");

64 第 4 章 Android GUI 开发 119 submenu.add(0, 2, 0, " 子菜单项二 "); return true; 子菜单的事件处理代码在 onoptionsitemselected() 中实现 MenusActivity.java 的完整代码如下 : package introduction.android.menusdemo; import android.app.actionbar; import android.app.activity; import android.os.bundle; import android.util.log; import android.view.contextmenu; import android.view.contextmenu.contextmenuinfo; import android.view.menu; import android.view.menuinflater; import android.view.menuitem; import android.view.submenu; import android.view.view; import android.widget.textview; public class MenusDemoActivity extends Activity { private TextView textview; /** Called when the activity is first created. */ public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.main); textview=(textview)findviewbyid(r.id.textview1); registerforcontextmenu(textview); // setcontentview(textview); public boolean onoptionsitemselected(menuitem item){ switch(item.getitemid()){ case 1: Log.i("menu","submenu item 1 selected"); case R.id.item1: textview.settext("item1 selected!"); break; case R.id.item2: textview.settext("item2 selected!"); break; case R.id.item3: default: textview.settext("item3 selected!"); break; Log.i("menu","other items selected"); break; return super.onoptionsitemselected(item);

65 120 Android 7 应用程序开发教程 public boolean oncreateoptionsmenu(menu menu){ MenuInflater inflater=getmenuinflater(); inflater.inflate(r.menu.mymenu, menu); SubMenu submenu=menu.addsubmenu(" 子菜单 "); submenu.seticon(android.r.drawable.ic_menu_crop); submenu.add(0,1,0," 子菜单项一 "); submenu.add(0, 2, 0, " 子菜单项二 "); return true; public boolean oncontextitemselected(menuitem item){ switch(item.getitemid()){ case R.id.item6: Log.i("menu","item6!"); break; case R.id.item7: default: Log.i("menu","item7!"); break; break; return super.oncontextitemselected(item); public void oncreatecontextmenu(contextmenu menu, View v, ContextMenuInfo menuinfo){ menu.add(0, R.id.item6, 0, " 上下文菜单项一 "); menu.add(0, R.id.item7, 0, " 上下文菜单项二 "); super.oncreatecontextmenu(menu, v, menuinfo); 4.6 Bitmap Bitmap 称为点阵图像或绘制图像, 是由称作像素 ( 图片元素 ) 的单个点组成的, 这些点通过不同的排列和染色以构成图样 Bitmap 是 Android 系统中图像处理最重要的类之一, 用它可以获取图像文件信息, 对图像进行剪切 旋转 缩放等操作, 并可以将图像保存成特定格式的文件 Bitmap 位于 android.graphics 包中, 不提供对外的构造方法, 只能通过 BitmapFactory 类进行实例化 利用 BitmapFactory 的 decodefile 方法可以从特定文件中获取 Bitmap 对象, 也可以使用 decoderesource() 从特定的图片资源中获取 Bitmap 对象 实例 BitmapDemo 从资源文件中创建 Bitmap 对象, 并对其进行一些操作, 运行效果如图 4.40 所示

66 第 4 章 Android GUI 开发 121 其对应布局文件 Main.xml 的内容如下 : <?xml version="1.0" encoding="utf-8"?> 图 4.40 Bitmap 对象的效果 <LinearLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <SeekBar android:id="@+id/seekbarid" android:layout_width="fill_parent" /> <ImageView android:id="@+id/imageview" android:src="@drawable/im01" /> </LinearLayout> BitmapDemoActivity.Java 的代码如下 : package introduction.android.bitmapdemo; import com.sie.bitmapdemo.r; import android.app.activity; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.matrix; import android.os.bundle; import android.widget.imageview; import android.widget.seekbar; import android.widget.seekbar.onseekbarchangelistener;

67 122 Android 7 应用程序开发教程 import android.widget.textview; public class BitmapDemoActivity extends Activity { ImageView myimageview; Bitmap mybmp, newbmp; int bmpwidth, bmpheight; SeekBar seekbarrotate; float rotangle; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); myimageview=(imageview)findviewbyid(r.id.imageview); // 由 Resource 载入图片 mybmp=bitmapfactory.decoderesource(getresources(), R.drawable.im01); bmpwidth=mybmp.getwidth(); bmpheight=mybmp.getheight(); // 实例化 matrix Matrix matrix=new Matrix(); // 设定 Matrix 属性 x y 缩放比例为 1.5 matrix.postscale(1.5f, 1.5F); // 顺时针旋转 45 度 matrix.postrotate(45.0f); newbmp=bitmap.createbitmap(mybmp, 0, 0, bmpwidth, bmpheight, matrix, true); seekbarrotate=(seekbar)findviewbyid(r.id.seekbarid); seekbarrotate.setonseekbarchangelistener(onrotate); private SeekBar.OnSeekBarChangeListener onrotate=new SeekBar.OnSeekBarChangeListener(){ public void onstoptrackingtouch(seekbar seekbar) { public void onstarttrackingtouch(seekbar seekbar) { ; public void onprogresschanged(seekbar seekbar, int progress, { boolean fromuser) Matrix m=new Matrix(); m.postrotate((float)progress*3.6f); newbmp=bitmap.createbitmap(mybmp, 0, 0, bmpwidth, bmpheight, m, true); myimageview.setimagebitmap(newbmp);

68 第 4 章 Android GUI 开发 123 本实例实现了拖动进度条图片旋转的效果 使用 BitmapFactory 从资源中载入图片, 并获取图片的宽和高, 之后使用 Matrix 类对图片进行缩放和旋转操作 4.7 对话框 对话框是人机交互过程中十分常见的组件, 一般用于在特定条件下对用户显示一些信息, 可以增强应用的友好性 Dialog 类是对话框的基类 对话框虽然可以在界面上显示, 但是 Dialog 不是 View 类的子类, 而是直接继承自 java.lang.object 类 Dialog 对象也有自己的生命周期, 其生命周期由创建它的 Activity 进行管理 Activity 可以调用 showdialog(int id) 将不同 ID 的对话框显示出来, 也可以调用 dismissdialog(int id) 方法将 ID 标识的对话框从用户界面中关闭掉 当 Activity 调用了 showdialog (ID) 方法, 对应 ID 的对话框没有被创建时,Android 系统会回调 OnCreateDialog(ID) 方法来创建具有该 ID 的对话框 在 Activity 中创建的对话框都会被 Activity 保存, 下次 showdialog(id) 方法被调用时, 若该 ID 的对话框已经被创建, 则系统不会再次调用 OnCreateDialog(ID) 方法创建该对话框, 而是会回调 onpreparedialog(int id, Dialog dialog) 方法, 该方法允许对话框在被显示之前做一些修改 常用的对话框有 AlertDialog 和 ProgressDialog, 本节将通过实例讲解这两种对话框的使用方法 AlertDialog AlertDialog 对话框是十分常用的用于显示信息的方式, 最多可提供三个按钮 AlertDialog 不能直接通过构造方法构建, 而要由 AlertDialog.Builder 类来创建 AlertDialog 对话框的标题 按钮以及按钮要响应的事件也由 AlertDialog.Builder 设置 在使用 AlertDialog. Builder 创建对话框时常用的几个方法如下 settitle(): 设置对话框中的标题 seticon(): 设置对话框中的图标 setmessage(): 设置对话框的提示信息 setpositivebutton(): 为对话框添加 yes 按钮 setnegativebutton(): 为对话框添加 no 按钮 setneutralbutton(): 为对话框添加第三个按钮 下面通过实例来学习创建 AlertDialog 的方法 创建 Android 工程 DialogDemo, 并在 main.xml 中添加两个按钮, 分别为 AlertDialog 和 ProcessDialog 其 main.xml 代码如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="fill_parent"

69 124 Android 7 应用程序开发教程 android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:text="dialog 演示 " /> <Button android:id="@+id/button1" android:layout_width="match_parent" android:text="alertdialog" /> <Button android:id="@+id/button2" android:layout_width="match_parent" android:text="progressdialog" /> </LinearLayout> 其运行效果如图 4.41 所示 处理 AlertDialog 按钮单击事件的代码为 : btn=(button)findviewbyid(r.id.button1); btn.setonclicklistener(new OnClickListener(){ ); public void onclick(view v){ showdialog(alert_dlg); 单击 AlertDialog 按钮, 调用 showdialog(alert_dlg), 系统回调 oncreatedialog(int id) 方法, 创建并弹出 AlertDialog 对话框, 如图 4.42 所示 图 4.41 AlertDialog 的运行效果 图 4.42 单击 AlertDialog 按钮的效果

70 第 4 章 Android GUI 开发 125 相关代码为 : protected Dialog oncreatedialog(int id){ Dialog dialog=null; switch(id){ case ALERT_DLG: AlertDialog.Builder builder=new AlertDialog.Builder(DialogDemoActivity.this); builder.seticon(android.r.drawable.ic_dialog_info); builder.settitle("alertdialog"); builder.setmessage(" 这是一个 AlertDialog"); builder.setpositivebutton("positive",new DialogInterface.OnClickListener(){ public void onclick(dialoginterface dialog, int which){ Log.i("DialogDemo","OK 按钮被单击!"); ); builder.setnegativebutton("negative",new DialogInterface.OnClickListener(){ public void onclick(dialoginterface dialog, int which){ Log.i("DialogDemo","Cancel 按钮被单击!"); ); builder.setneutralbutton("neutral",new DialogInterface.OnClickListener(){ public void onclick(dialoginterface dialog, int which){ Log.i("DialogDemo","Neutral 按钮被单击!"); ); default: dialog=builder.create(); break; break; return dialog; oncreatedialog() 方法中创建了带有三个按钮的 AlertDialog, 并且为每个按钮添加了事件处理方法, 以便获知用户单击了哪个按钮 ProgressDialog ProgressDialog 是一个带有进度条的对话框, 当应用程序在完成比较耗时的工作时, 使用该对话框可以为用户提供一个总进度上的提示

71 126 Android 7 应用程序开发教程 为 main.xml 布局中的 ProgressDialog 按钮添加事件处理代码 : progressbtn=(button)findviewbyid(r.id.button2); progressbtn.setonclicklistener(new OnClickListener(){ public void onclick(view v){ showdialog(progress_dlg); ); 单击 ProgressDialog 按钮, 调用 showdialog(progress_dlg), 系统回调 oncreatedialog(int id) 方法, 创建并弹出 ProgressDialog 对话框, 如图 4.43 所示 oncreatedialog() 方法中的相关代码如下 : case PROGRESS_DLG: 图 4.43 单击 ProgressDialog 按钮的效果 progressdialog=new ProgressDialog(this); // 设置水平进度条 progressdialog.setprogressstyle(progressdialog.style_horizontal); // 设置进度条最大值为 100 progressdialog.setmax(100); // 设置进度条当前值为 0 progressdialog.setprogress(0); dialog=progressdialog; new Thread(new Runnable(){ int count=0; public void run(){ while(progressdialog.getprogress()<100){ count+=3; progressdialog.setprogress(count); try { Thread.sleep(1000); catch(interruptedexception e){ // TODO Auto-generated catch block e.printstacktrace(); ).start(); break;

72 第 4 章 Android GUI 开发 Toast 和 Notification Toast 和 Notification 是 Android 系统为用户提供的轻量级的信息提醒机制 这种方式不会打断用户当前的操作, 也不会获取到焦点, 非常方便 本节我们通过实例学习 Toast 和 Notification 的使用方法 Toast 创建工程 NotificationDemo, 并实现如图 4.44 所示的布局 main.xml 的代码如下 : 图 4.44 工程布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:text="toast 和 Notification 演示 " /> <Button android:id="@+id/button1" android:text="toast" /> <Button

73 128 Android 7 应用程序开发教程 android:id="@+id/button2" android:text="notification" /> <Button android:id="@+id/button3" android:text="cancelnotification" /> </LinearLayout> 在 NotificationDemoActivity 中为每个按钮添加事件响应 单击 Toast 按钮, 运行效果如图 4.45 所示 相关代码如下 : Button toastbtn=(button)this.findviewbyid (R.id.button1); toastbtn.setonclicklistener(new View.OnClickListener(){ Toast.LENGTH_LONG).show(); ); public void onclick(view v){ Toast.makeText(NotificationDemoActivity.this, " 这是一个 Toast 演示!", Toast 用于向用户显示小信息量的提示, 它不会中断应用程序进程, 不会对用户操作造成任何干扰, 也不能与用户交互, 在信息显示后会自动消失 此处使用 Toast.makeText(Context context, CharSequence text, int duration) 方法来创建一个 Toast 其中, context 指显示 Toast 的上下文 ;text 指 Toast 中显示的文字内容 ; duration 指 Toast 显示延续的时间, 该时间可以直接指定, 也可以使用 Toast 提供 LENGTH_LONG 和 LENGTH_SHORT 常量 Toast.show() 方法可以将 Toast 对象显示出来 Toast 默认情况下显示在屏幕的下方, 可以通过 Toast.setGravity() 方法设置 Toast 的显示位置 例如如下代码 : Toast toast=toast.maketext(notificationdemoactivity.this, Toast.LENGTH_LONG); " 这是一个位于中间位置的 Toast", toast.setgravity(gravity.center, 0, 0); toast.show(); 显示效果如图 4.46 所示 图 4.45 单击 Toast 按钮的效果 Notification 图 4.46 显示效果 Notification 可以在手机屏幕顶部的状态栏显示一个带图标的通知, 同时播放声音或者使手机

74 第 4 章 Android GUI 开发 129 震动 Notification 可以扩展以显示详细信息, 单击该 Notification 还可以跳转到特定的 Activity 单击 Notification 按钮, 运行效果如图 4.47 所示, 在视图的状态栏出现 Notification 提示 按住 Notification 并下拉, 可将 Notification 内容进行扩展, 效果如图 4.48 所示 单击图标处, 应用程序跳转到 NoteActivity 视图, 运行效果如图 4.49 所示 单击 返回 按钮, 返回到 NotificationDemoActivity 视图 图 4.47 单击 Notification 按钮的效果 图 4.48 下拉 Notification 的效果 图 4.49 单击图标的效果 相关代码如下 : Button notifybtn=(button)this.findviewbyid(r.id.button2); notifybtn.setonclicklistener(new View.OnClickListener(){ public void onclick(view v){ context=getapplicationcontext(); String ns=context.notification_service; mnotificationmanager=(notificationmanager)getsystemservice(ns); int icon=r.drawable.icon01; CharSequence tickertext=" 这是一个 Notification!"; long when=system.currenttimemillis(); Notification.Builder builder=new Notification.Builder(context); builder.setsmallicon(icon); builder.setticker(tickertext);

75 130 Android 7 应用程序开发教程 builder.setwhen(when); notification=builder.getnotification(); CharSequence contenttitle="my notification"; CharSequence contenttext=" 单击这个 notification, 可以跳转到 NoteActivity."; Intent notificationintent=new Intent(context, NoteActivity.class); PendingIntent contentintent=pendingintent.getactivity(context, 0, notificationintent, 0); notification.setlatesteventinfo(context, contenttitle, contenttext, contentintent); ); notification.defaults=notification.default_sound; mnotificationmanager.notify(notification_id, notification); Notification.Builder 是 Android API Level 11 以上版本提供的 Notification 的创建类, 可以方便地创建 Notification 并设置各种属性 此处创建了一个 Notification, 并指定了显示内容和图标 Notification.setLatestEventInfo() 方法设定了当用户扩展 Notification 时显示的样式, 并通过 PendingIntent 对象指定了当用户单击扩展的 Notification 时应用程序如何跳转, 此处跳转至 NoteActivity NotificationManager.notify(int id,notification notification) 方法为 Notification 对象指定一个 ID 值, 并将该 Notification 对象显示到状态栏上 NotificationManager.cancel(int id) 方法会将 ID 指向的 Notification 对象取消掉 NoteActivity.java 的代码如下 : package introduction.android.notificationdemo; import android.app.activity; import android.content.intent; import android.os.bundle; import android.view.view; import android.widget.button; public class NoteActivity extends Activity { private Button btn; public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.other); btn=(button)this.findviewbyid(r.id.button1); btn.setonclicklistener(new View.OnClickListener(){ public void onclick(view v){ Intent intent=new Intent (NoteActivity.this,NotificationDemoActivity.class); ); startactivity(intent); NoteActivity 所使用的布局文件 other.xml 的代码如下 :

76 第 4 章 Android GUI 开发 131 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/textview1" android:text="noteactivity" /> <Button android:id="@+id/button1" android:text=" 返回 " /> </LinearLayout> Notification Group 当一个应用程序产生多个通知时,Android N 提供了新的 API, 支持将多个通知进行分组和折叠显示, 同时告诉用户共有多少个通知, 并且给出一个关于通知的摘要消息 实例 NotiDemo 演示了这一功能, 其界面很简单, 布局如图 4.50 所示 当每次点击 NOTIFY 按钮时, 该应用会产生一个通知消息, 而按钮下方的 TextView 会显示当前应用共产生了多少个通知 图 4.50 NotiDemo 布局该布局对应内容为 : <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=" xmlns:tools="

77 132 Android 7 应用程序开发教程 android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" tools:context="introduction.android.notidemo.mainactivity"> <TextView android:text="hello World!" /> <Button android:text="notify" android:layout_below="@+id/textview" android:layout_alignparentstart="true" android:layout_marginstart="52dp" android:layout_margintop="38dp" android:id="@+id/button" /> <TextView android:text="textview" android:layout_width="match_parent" android:layout_margintop="36dp" android:id="@+id/number_of_notifications" android:layout_below="@+id/button" android:layout_centerhorizontal="true" /> </RelativeLayout> MainActivity.java 的代码为 : package introduction.android.notidemo; import android.app.activity; import android.app.notification; import android.app.notificationmanager; import android.content.context; import android.os.bundle; import android.service.notification.statusbarnotification; import android.support.v4.app.notificationcompat; import android.util.log; import android.view.view; import android.widget.button; import android.widget.textview; public class MainActivity extends Activity { private static final int REQUEST_CODE = 2323; private static final String TAG = "NotiDemo"; private static final String NOTIFICATION_GROUP ="intoduction.android.notidemo.group";

78 第 4 章 Android GUI 开发 133 private static final int NOTIFICATION_GROUP_SUMMARY_ID = 1; private TextView mnumberofnotifications; private NotificationManager mnotificationmanager; private static int snotificationid = NOTIFICATION_GROUP_SUMMARY_ID + 1; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); mnotificationmanager = (NotificationManager) getsystemservice( Context.NOTIFICATION_SERVICE); mnumberofnotifications = (TextView)findViewById(R.id.number_of_notifications); Button btn= (Button) findviewbyid(r.id.button); btn.setonclicklistener(new View.OnClickListener() { ); public void onclick(view view) { addnotificationandupdatesummaries(); private void addnotificationandupdatesummaries() { // [BEGIN create_notification] // Create a Notification and notify the system. final NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setSmallIcon(R.mipmap.ic_notification).setContentTitle(getString(R.string.app_name)).setContentText(getString(R.string.sample_notification_content)).setAutoCancel(true).setGroup(NOTIFICATION_GROUP); final Notification notification = builder.build(); mnotificationmanager.notify(getnewnotificationid(), notification); // [END create_notification] Log.i(TAG, "Add a notification"); updatenotificationsummary(); updatenumberofnotifications(); /** * Adds/updates/removes the notification summary as necessary. */ protected void updatenotificationsummary() { int numberofnotifications = getnumberofnotifications(); if (numberofnotifications > 1) { // Add/update the notification summary. String notificationcontent = getstring(r.string.sample_notification_summary_content, numberofnotifications); final NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setSmallIcon(R.mipmap.ic_notification).setStyle(new NotificationCompat.BigTextStyle().setSummaryText(notificationContent)).setGroup(NOTIFICATION_GROUP).setGroupSummary(true); final Notification notification = builder.build(); mnotificationmanager.notify(notification_group_summary_id, notification);

79 134 Android 7 应用程序开发教程 else { // Remove the notification summary. mnotificationmanager.cancel(notification_group_summary_id); /** * Requests the current number of notifications from the {@link NotificationManager and * display them to the user. */ protected void updatenumberofnotifications() { final int numberofnotifications = getnumberofnotifications(); mnumberofnotifications.settext(getstring(r.string.active_notifications, numberofnotifications)); Log.i(TAG, getstring(r.string.active_notifications, numberofnotifications)); /** * Retrieves a unique notification ID. */ public int getnewnotificationid() { int notificationid = snotificationid++; // Unlikely in the sample, but the int will overflow if used enough so we skip the summary // ID. Most apps will prefer a more deterministic way of identifying an ID such as hashing // the content of the notification. if (notificationid == NOTIFICATION_GROUP_SUMMARY_ID) { notificationid = snotificationid++; return notificationid; private int getnumberofnotifications() { // [BEGIN get_active_notifications] // Query the currently displayed notifications. final StatusBarNotification[] activenotifications = mnotificationmanager.getactivenotifications(); // [END get_active_notifications] // Since the notifications might include a summary notification remove it from the count if // it is present. for (StatusBarNotification notification : activenotifications) { if (notification.getid() == NOTIFICATION_GROUP_SUMMARY_ID) { return activenotifications.length - 1; return activenotifications.length; 对应的 strings.xml 代码为 : <resources> <string name="app_name">notidemo</string> <string name="active_notifications"> 目前的通知数目 : %1$d</string>

80 第 4 章 Android GUI 开发 135 <string name="sample_notification_content"> 这是一个通知的示例 </string> <string name="sample_notification_summary_content"> 共有 %d 个通知 </string> </resources> 点击 NOTIFY 按钮, 运行效果如图 4.51 所示 图 4.51 运行效果 Android N 通过 NotificationCompat 类构建通知的模板信息, 例如通知的图标 通知的标题 通知的内容 通知是否需要进行分组等, 然后由 NotificationCompat 构建 Notification 通知对象, 并由 NotificationManager 发送通知 相关代码如下 : final NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setSmallIcon(R.mipmap.ic_notification).setContentTitle(getString(R.string.app_name)).setContentText(getString(R.string.sample_notification_content)).setAutoCancel(true).setGroup(NOTIFICATION_GROUP); final Notification notification = builder.build(); mnotificationmanager.notify(getnewnotificationid(), notification); 在设置了通知分组的情况下,Android N 会自动将同一个应用的通知进行合并分组实现, Android N 可以通过 NotificationCompat 设置通知分组的显示消息 String notificationcontent = getstring(r.string.sample_notification_summary_content, numberofnotifications); final NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setSmallIcon(R.mipmap.ic_notification).setStyle(new NotificationCompat.BigTextStyle().setSummaryText(notificationContent)).setGroup(NOTIFICATION_GROUP).setGroupSummary(true); 默认情况下, 通知栏会分别显示每条通知 当产生的通知数目较多时, 之前的通知会被折叠, 并以 + 折叠通知数目 的方式进行显示, 如图 4.52 所示

81 136 Android 7 应用程序开发教程 将折叠效果下的通知分组下拉, 会得到非折叠效果的通知列表, 如图 4.53 所示 而这也是不进行通知分组折叠时的效果, 即 NotificationCompat 不进行 setgroup 设置时的效果 图 4.52 通知分组和折叠效果 图 4.53 非折叠的通知列表 4.9 多窗口模式 Android N 支持多窗口模式, 或者叫分屏模式, 即在屏幕上可以同时显示多个窗口 在手机模式下, 两个应用可以并排或者上下同时显示, 如图 4.54 所示, 屏幕上半部分的窗口是系统的 CLOCK 应用, 下半部分是系统设置功能 用户可以拖动两个应用之间的分界线改变两个窗口的大小, 放大其中一个应用, 同时缩小另一个应用 在电视设备上, 可以实现 画中画 功能 在分屏模式下, 各个窗口的应用都可以正常运行, 但是只能有一个窗口获得焦点, 而另外的窗口则属于暂停状态 Android N 用户可以通过以下方式切换到多窗口模式 : (1) 用户打开 Overview 屏幕并长按 Activity 标题, 可以拖动该 Activity 至屏幕突出显示的区域, 使 Activity 进入多窗口模式 (2) 用户长按 Overview 按钮, 设备上当前的 Activity 将进入多窗口模式, 同时将打开 Overview 屏幕, 用户可在该屏幕中选择要共享屏幕的另一个 Activity 用户可以在两个 Activity 共享屏幕的同时在这两个 Activity 之间拖放数据 图 4.54 分屏模式

82 第 4 章 Android GUI 开发 137 默认情况下,Android N 的 Activity 都是开启多窗口模式的 例如, 我们通过 Android Studio 构建一个默认的空 Activity 应用 MultiScreenDemo, 无须做任何修改, 该 Activity 即可使用多窗口模式, 运行效果如图 4.55 所示 图 4.55 自开发应用的多窗口模式 我们在 MainActivity 上添加一个按钮, 并实现点击打开第二个 Activity 的功能, 代码如下 : public class MainActivity extends Activity { protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); Button btn=findviewbyid(r.id.button); btn.setonclicklistener(new View.OnClickListener() { ); public void onclick(view view) { Intent intent=new Intent(MainActivity.this,Main2Activity.class); startactivity(intent); 点击 新窗口 按钮后, 第二个窗口会被创建, 并覆盖掉第一个窗口, 如图 4.56 所示 默认情况下, 同一个应用的多个 Activity 会共用同一个窗口, 且无法分配到不同窗口中 若希望同一个应用的不同窗体可以被分配到不同窗口中, 需要在启动新窗体时给 Intent 设置一个 FLAG_ACTIVITY_LAUNCH_ADJACENT 标志, 这样新 Activity 就会在新的栈中被启动, 独立于原来的 Activity, 进而实现两个 Activity 被放置于不同的窗口中, 如图 4.57 所示

83 138 Android 7 应用程序开发教程 图 4.56 新窗口 图 4.57 同一应用的两个窗口 关键代码如下 : Intent intent=new Intent(MainActivity.this,Main2Activity.class); intent.setflags(intent.flag_activity_launch_adjacent Intent.FLAG_ACTIVITY_NEW_TASK); startactivity(intent); Android N 系统为 Activity 增添了 <layout> 清单元素对 Activity 在多窗口模式中的行为进行支持, 包括以下几种属性 : android:defaultwidth, 以自由形状模式启动时 Activity 的默认宽度 android:defaultheight, 以自由形状模式启动时 Activity 的默认高度 android:gravity, 以自由形状模式启动时 Activity 的初始位置 请参阅 Gravity 的参考资料, 了解合适的值进行设置 android:minimalheight android:minimalwidth, 分屏和自由形状模式中 Activity 的最小高度和最小宽度 如果用户在分屏模式中移动分界线, 使 Activity 尺寸低于指定的最小值, 系统会将 Activity 裁剪为用户请求的尺寸 例如, 以下代码显示了如何指定 Activity 在自由形状模式显示时 Activity 的默认大小 位置和最小尺寸 : <activity android:name=".myactivity"> <layout android:defaultheight="500dp" </activity> android:defaultwidth="600dp" android:gravity="top end" android:minimalheight="450dp" android:minimalwidth="300dp" /> 如果不想让 Activity 使用多窗口模式, 只需要在清单文件中为 Activity 节点设置 :

84 第 4 章 Android GUI 开发 139 android:resizeableactivity= false 此属性设置为 false,activity 将不支持多窗口模式 在该值为 false 的情况下, 如果用户尝试在多窗口模式下启动 Activity, 该 Activity 将全屏显示 各位读者可以自行尝试 4.10 界面事件响应 事件是 Android 平台与用户交互的手段 当用户对手机进行操作时, 会产生各种各样的输入事件,Android 框架捕获到这些事件, 进而进行处理 Android 平台提供了多种用于获取用户输入事件的方式, 考虑到用户事件都是在特定的用户界面中产生的, 因此 Android 选用特定 View 组件来获取用户输入事件的方式, 由 View 组件提供事件的处理方法 这就是为什么 View 类内部带有处理特定事件的监听器 事件监听器 监听器用于对特定事件进行监听, 一旦监听到特定事件, 则由监听器截获该事件, 并回调自身的特定方法对事件进行处理 在本章之前的实例中, 我们使用的事件处理方式都是监听器 根据用户输入方式的不同,View 组件将截获的事件分为 6 种, 对应以下 6 种事件监听器接口 (1)OnClickListener 接口 : 此接口处理的是单击事件, 例如, 在 View 上进行单击动作, 在 View 获得焦点的情况下单击 确定 按钮或者单击轨迹球都会触发该事件 当单击事件发生时, OnClickListener 接口会回调 public void onclick(view v) 方法对事件进行处理 其中参数 v 指的是发生单击事件的 View 组件 (2)OnLongClickListener 接口 : 此接口处理的是长按事件, 当长时间按住某个 View 组件时触发该事件 其对应的回调方法为 public boolean onlongclick(view v), 当返回 true 时, 表示已经处理完此事件, 若事件未处理完, 则返回 false, 该事件还可以继续被其他监听器捕获并处理 (3)OnFocusChangeListener 接口 : 此接口用于处理 View 组件焦点改变事件 当 View 组件失去或获得焦点时会触发该事件, 其对应的回调方法为 public void onfocuschange(view v, Boolean hasfocus), 其中参数 v 表示产生事件的事件源,hasFocus 表示事件源的状态, 即是否获得焦点 (4)OnKeyListener 接口 : 此接口用于对手机键盘事件进行监听, 当 View 获得焦点并且键盘被敲击时会触发该事件 其对应的回调方法为 public boolean onkey(view v, int keycode, KeyEvent event), 其中参数 keycode 为键盘码, 参数 event 为键盘事件封装类的对象 (5)OnTouchListener 接口 : 此接口用来处理手机屏幕事件, 当在 View 的范围内有触摸 按下 抬起 滑动等动作时都会触发该事件, 并触发该接口中的回调方法, 其对应的回调方法为 public boolean ontouch(view v, MotionEvent event), 对应的参数同上 (6)OnCreateContextMenuListener 接口 : 此接口用于处理上下文菜单被创建的事件, 其对应的回调方法为 public void oncreatecontextmenu(contextmenu menu, View v, ContextMenuInfo info), 其中参数 menu 为事件的上下文菜单, 参数 info 是该对象中封装了有关上下文菜单的其他信息 在

85 140 Android 7 应用程序开发教程 4.5 节的实例 MenusDemo 中, 创建上下文菜单使用的是 registerforcontextmenu(view v) 方法, 其本质是为 View 组件 v 注册该接口, 并实现了相应的回调方法 回调事件响应 在 Android 框架中, 除了可以使用监听器进行事件处理之外, 还可以通过回调机制进行事件处理 Android SDK 为 View 组件提供了 5 个默认的回调方法, 如果某个事件没有被任意一个 View 处理, 就会在 Activity 中调用响应的回调方法, 这些方法分别说明如下 (1)public boolean onkeydown(int keycode, KeyEvent event) 方法是接口 KeyEvent. Callback 中的抽象方法, 当键盘按键被按下时由系统调用 参数 keycode 即键盘码, 系统根据键盘码得知按下的是哪个按钮 参数 event 为按钮事件的对象, 包含触发事件的详细信息, 例如事件的类型 状态等 当此方法的返回值为 True 时, 代表已完成处理此事件, 返回 false 表示该事件还可以被其他监听器处理 (2)public boolean onkeyup(int keycode, KeyEvent event) 方法也是接口 KeyEvent. Callback 中的抽象方法, 当按钮向上弹起时被调用, 参数与 onkeydown() 完全相同 (3)public boolean ontouchevent(motionevent event) 方法在 View 中定义, 当用户触摸屏幕时被自动调用 参数 event 为触摸事件封装类的对象, 封装了该事件的相关信息 当用户触摸到屏幕, 屏幕被按下时,MotionEvent.getAction() 的值为 MotionEvent.ACTION_ DOWN; 当用户将触控物体离开屏幕时,MotionEvent.getAction() 的值为 MotionEvent. ACTION_UP; 当触控物体在屏幕上滑动时,MotionEvent.getAction() 的值为 MotionEvent. ACTION_MOVE ontouchevent 方法的返回值为 true 表示事件处理完成, 返回 false 表示未完成 (4)public boolean ontrackballevent(motionevent event) 方法的功能是处理手机中轨迹球的相关事件, 可以在 Activity 中重写, 也可以在 View 中重写 参数 event 为手机轨迹球事件封装类的对象 该方法的返回值为 true 表示事件处理完成, 返回值为 false 表示未完成 (5)protected void onfocuschanged(boolean gainfocus, int direction, Rect previouslyfocusedrect) 方法只能在 View 中重写, 当 View 组件焦点改变时被自动调用, 参数 gainfocus 表示触发该事件的 View 是否获得了焦点, 获得焦点为 true, 参数 direction 表示焦点移动的方向, 参数 previouslyfocusedrect 是在触发事件的 View 的坐标系中前一个获得焦点的矩形区域 界面事件响应实例 在之前的章节中, 多次使用监听器对事件进行处理, 读者应该已经很熟悉了 本节通过一个实例来演示回调事件响应的处理过程, 该实例 EventDemo 的运行效果如图 4.58 所示

86 第 4 章 Android GUI 开发 141 其布局文件 main.xml 内容如下 : <?xml version="1.0" encoding="utf-8"?> 图 4.58 实例 EventDemo 的运行效果 <LinearLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:text=" 回调事件处理演示 " /> <LinearLayout android:orientation="horizontal"> <Button android:id="@+id/button1" android:focusableintouchmode="true" android:text=" 按钮 1"/> <Button android:id="@+id/button2" android:focusableintouchmode="true" android:text=" 按钮 2"/> <Button android:id="@+id/button3"

87 142 Android 7 应用程序开发教程 </LinearLayout> android:focusableintouchmode="true" android:text=" 按钮 3"/> </LinearLayout> 当用户在屏幕上做移动触摸 单击按钮等操作时, 主 Activity EventDemo 会捕获相应事件并进行处理, 在 LogCat 中打印相关内容, 运行效果如图 4.59 所示 EventDemo.java 代码如下 : package introduction.android.eventdemo; 图 4.59 Activity EventDemo 捕获事件 import android.app.activity; import android.content.context; import android.graphics.rect; import android.os.bundle; import android.util.log; import android.view.keyevent; import android.view.motionevent; import android.view.view; import android.view.view.onfocuschangelistener; import android.widget.button; import android.widget.toast; public class EventDemo extends Activity implements OnFocusChangeListener { Button[] buttons=new Button[3]; public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.main); buttons[0]=(button)findviewbyid(r.id.button1); buttons[1]=(button)findviewbyid(r.id.button2); buttons[2]=(button)findviewbyid(r.id.button3); for(button button :buttons){ button.setonfocuschangelistener(this); // 按钮按下触发的事件 public boolean onkeydown(int keycode,keyevent event)

res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml

res/layout 目录下的 main.xml 源码 : <?xml version=1.0 encoding=utf 8?> <TabHost android:layout_height=fill_parent xml 拓展训练 1- 界面布局 1. 界面布局的重要性做应用程序, 界面是最基本的 Andorid 的界面, 需要写在 res/layout 的 xml 里面, 一般情况下一个 xml 对应一个界面 Android 界面布局有点像写 html( 连注释代码的方式都一样 ), 要先给 Android 定框架, 然后再在框架里面放控件,Android 提供了几种框架,AbsoluteLayout,LinearLayout,

More information

预览图 : (2) 在 SelectCity.java 中增加控件, 用于绑定 select_city 文件的 ListView, TextView,EditTest 等控件 代码和注释如下 :

预览图 : (2) 在 SelectCity.java 中增加控件, 用于绑定 select_city 文件的 ListView, TextView,EditTest 等控件 代码和注释如下 : EditText 实现城市搜索 1801210778 邹宇航 摘要 : 使用 EditText 实现搜索城市的功能, 以此为依据更新 ListView 1. 效果图 : 2. 主要步骤 (1) 在 select-city.xml 布局文件中中添加 EditText 控件用作搜索框, 然后添加 ListView 控件用来显示城市名字内容 代码如下 : 预览图 : (2) 在 SelectCity.java

More information

主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new

主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new ListView 自訂排版 主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new int[]{r.drawable.dog1, R.drawable.dog2,

More information

Android 开发教程

Android 开发教程 封面 1 GUI 可视化设计器 DroidDraw DroidDraw 是一个基于 Java Swing 的 Android 界面设计器, 可以通过它来生成复杂的 Android Layout XML 文 件,Android 的 Layout 和 Swing Layout 中有很好的对应, 设计器的代码编写起来比较容易 2 AnDroidDraw AnDroidDraw 是一个与 DroidDraw

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 第 章.1 Android UI 基本概念 用户界面 (User Interface,UI) 是用户与设备之间进行信息交流的直接媒介, 是决定用户体验最重要的部分 相比于早期的计算机的主要交互界面 批处理界面和命令行界面, 现在更为流行的是更简单直接的用户图形界面 (Graphical User Interface, GUI) GUI 简单易用, 受众面广, 直接推动了个人计算机的发展 目前, 主流大众的操作系统都采用了

More information

Lecture01_Android介绍

Lecture01_Android介绍 移动平台应用软件开发 Android 介绍 主讲 : 张齐勋 zhangqx@ss.pku.edu.cn 移动平台应用软件开发 课程建设小组 北京大学 二零一七年秋北京 Android是什么 Android不仅仅是一个操作系统 它更是一个完整的软件框 架 Android基于Linux内核 2005年Google公司收购了Android公司 Google公司选择使用Apache许可证开放Android源码

More information

Android Android Android SDK iv

Android Android Android SDK iv Android Market Google Android SDK Apple Google Microsoft b2c b 2010 Internet Android how why iii Android 240... Android Android SDK iv Android Market Google Android SDK Visual C++ Java N-tier J2EE Unix/Linux

More information

Android Fragment

Android Fragment Android Fragment 建國科技大學資管系饒瑞佶 2017/10 V1 Android 3.0 後才支援 Fragment 解決部分 App 適應螢幕大小的問題 它類似於 Activity, 可以像 Activity 可以擁有自己的版面設計, 也和 Activity 一樣有自己的生命週期 ( 具備 oncreate() oncreateview() 與 onpause() 方法 ) LifeCycle

More information

用手機直接傳值不透過網頁連接, 來當作搖控器控制家電 ( 電視遙控器 ) 按下按鍵發送同時會回傳值來確定是否有送出 問題 :1. 應該是使用了太多 thread 導致在傳值上有問題 2. 一次按很多次按鈕沒辦法即時反應

用手機直接傳值不透過網頁連接, 來當作搖控器控制家電 ( 電視遙控器 ) 按下按鍵發送同時會回傳值來確定是否有送出 問題 :1. 應該是使用了太多 thread 導致在傳值上有問題 2. 一次按很多次按鈕沒辦法即時反應 專題進度 老師 : 趙啟時老師 學生 : 陳建廷 2013/10/13 用手機直接傳值不透過網頁連接, 來當作搖控器控制家電 ( 電視遙控器 ) 按下按鍵發送同時會回傳值來確定是否有送出 問題 :1. 應該是使用了太多 thread 導致在傳值上有問題 2. 一次按很多次按鈕沒辦法即時反應 程式碼 : package com.example.phone; import java.util.arraylist;

More information

Android Service

Android Service Android Service- 播放音樂 建國科技大學資管系 饒瑞佶 2013/7 V1 Android Service Service 是跟 Activity 並行 一個音樂播放程式若沒使用 Service, 即使按 home 鍵畫面離開之後, 音樂還是照播 如果再執行一次程式, 新撥放的音樂會跟先前撥放的一起撥, 最後程式就會出錯 執行中的程式完全看不到! 但是, 寫成 Service 就不同了

More information

单击以编辑母片 Content 标题样式 LinearLayout 排版模式 TableLayout 排版模式 RelativeLayout 排版模式 AbsoluteLayout 排版模式 FrameLayout 排版模式 GridLayout 排版模式 TabWidget 切換卡 Lab 5 2

单击以编辑母片 Content 标题样式 LinearLayout 排版模式 TableLayout 排版模式 RelativeLayout 排版模式 AbsoluteLayout 排版模式 FrameLayout 排版模式 GridLayout 排版模式 TabWidget 切換卡 Lab 5 2 单击以编辑母片标题样式 安卓系统 Android 的排版 授课老师 : 谢兆贤 2016/4/18 1 单击以编辑母片 Content 标题样式 LinearLayout 排版模式 TableLayout 排版模式 RelativeLayout 排版模式 AbsoluteLayout 排版模式 FrameLayout 排版模式 GridLayout 排版模式 TabWidget 切換卡 Lab 5

More information

單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e

單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e Android Studio Debugging 本篇教學除了最基本的中斷點教學之外, 還有條件式中斷的教學 條件式中斷是進階的除錯技巧, 在某些特定情況中, 我們有一個函數可能會被呼叫數次, 但是我們只希望在某種條件成立時才進行中斷, 進而觀察變數的狀態 而條件式中斷這項技巧正是符合這項需求 本教學分兩部分 單步除錯 (Page2~11, 共 10) 條件式中斷點 (Page12~17, 共 6)

More information

人民邮电

人民邮电 第 2 章 布 局 布 局 是 所 有 带 界 面 的 Android 程 序 的 开 端 布 局 应 用 得 好 坏 直 接 决 定 了 程 序 的 用 户 体 验 虽 然 布 局 看 似 没 有 组 件 复 杂, 但 也 涉 及 到 了 很 多 技 巧 在 各 大 公 司 的 面 试 题 中 也 会 经 常 遇 到 关 于 布 局 的 一 些 问 题 通 过 这 些 问 题 可 以 考 查 应

More information

Lecture01_Android介绍

Lecture01_Android介绍 移动平台应用软件开发 Android 介绍 主讲 : 张齐勋 zhangqx@ss.pku.edu.cn 移动平台应用软件开发 课程建设小组 北京大学 二零一八年秋北京 Android 是什么 Android 不仅仅是一个操作系统, 它更是一个完整的软件框架 Android 基于 Linux 内核 2005 年 Google 公司收购了 Android 公司 Google 公司选择使用 Apache

More information

题目

题目 开发 Android 应用 目的 : 帮助大家了解 Android 平台开发 作者 : 王威威 技术爱好 : linux,qt, 嵌入式开发 MSN : wangweiweicdma@hotmail.com Email : wang.weiwei1@ztenc.com.cn wangjiecdma@126.com 下载开发资源 1 下载最新的 Android SDK http://code.google.com/android/download.html

More information

第一章 Android 简介与开发环境搭建

第一章 Android 简介与开发环境搭建 安卓开发环境与常用布局 第一章 Android 简介与开发环境搭建 本章目标 3G 的概念 Android 的改变 Android 开发环境的搭建编写第一个 Android 程序 Android 程序的目录结构 手机发展史 1. 3G 的概念 3G 全称为 :3rd Generation, 中文含义即为第三代数字通信, 是指将无线通信与国际互联网等多媒体通信结合的新一代移动通信系统 2. 符合 3G

More information

Chapter 4

Chapter 4 Chapter 4 手機控制項應用 元件佈局 線性佈局共有兩個方向 : 垂直 (vertical) 水帄 (horizontal) 決定垂直或是水帄的屬性為 Orientation android:orientation="vertical" 線性佈局就是將在 < LinearLayout > 內的元件以線性的方式來呈現

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 第 3 章 Android 控件进阶 要设计出让用户喜欢的 Android 应用程序界面, 除了需要用到在第 2 章讲的最基本的 TextView EditText 和 Button 控件外, 还要用到其他控件, 如 ImageButton 控件 ImageView 控件 RadioButton 控件 CheckBox 控件和 ListView 控件等 本章主要讲解功能强大 应用广泛的一些控件 3.1

More information

01_Service

01_Service 移动平台应用软件开发 Service 主讲 : 张齐勋 zhangqx@ss.pku.edu.cn 移动平台应用软件开发 课程建设小组 北京大学 二零一七年 什么是 Service 与 Activity 一样, 同属 Android 基本组件 后台运行, 不与用户交互, 没有可视化界面 最常见的 Service 如 : 在后台播放歌曲 后台执行文件的下载 同样需在 AndroidManifest.xml

More information

Microsoft Word - 扉页.doc

Microsoft Word - 扉页.doc 第 3 章 Andro 常用基本控件 我们在进行界面布局时, 添加的按钮 文本框 编辑框和图片等, 都是 Andro 的基本控件 这些控件实现了程序的一些基本功能 本章将针对这类控件进行详细的介绍, 使读者掌握基本控件的使用, 开发出简单的 Andro 程序 3.1 文本控件概述 Andro 系统提供给用户已经封装好的界面控件称为系统控件 系统控件更有利于帮助用户进行快速开发, 同时能够使 Andro

More information

Android 编程基础 Android 开发教程 & 笔记 1

Android 编程基础 Android 开发教程 & 笔记 1 Android 开发教程 & 笔记 1 多式样 ProgressBar 撰写 : 地狱怒兽 联系 :zyf19870302@126.com 普通圆形 ProgressBar 该类型进度条也就是一个表示运转的过程, 例如发送短信, 连接网络等等, 表示一个过程正 在执行中 一般只要在 XML 布局中定义就可以了

More information

0511-Android程式之GPS應用_專題週記4

0511-Android程式之GPS應用_專題週記4 逢甲大學通訊工程學系專題研究 Android 程式之 GPS 應用 專題週記 0511 學生姓名 陳彥儒 D0035131 廖元譽 D0077791 指導老師 楊豐瑞老師繳交日期 2014.05.11 1 匯入 GoogleMap 1.1 取得授權步驟 目前進度 取得 Google 授權鑰匙 實作程式尚未成功 1.1.1 建立個人的 keystore 1.1.2 由個人的 keystore 查詢 SHA1

More information

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 odps-sdk 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基 开放数据处理服务 ODPS SDK SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基础功能的主体接口, 搜索关键词 "odpssdk-core" 一些

More information

Dynamic Layout in Android

Dynamic Layout in Android Dynamic Layout in Android 建國科技大學資管系 饒瑞佶 2013/5 V1 Layout 多半都透過 res/layout/xml 格式設定來達成 Android 是 OOP, 所以可以動態產生 Layout 重點是 Layout 的階層關係 (Hierarchy) 需要處理對應事件 最後一樣用 setcontentview 加入 Layout 一 加入現有 Layout 中

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 第 3 章 多个用户界面的程序设计 3.1 页面的切换与传递参数值 3.1.1 传递参数组件 Intent Intent 是 Android 系统的一种运行时的绑定机制, 在应用程序运行时连接两个不同组件 在 Android 的应用程序中不管是页面切换还是传递数据或是调用外部程序都可能要用到 Intent Intent 负责对应用中某次操作的动作 动作涉及的数据 附加数据进行描述, Android

More information

PowerPoint 簡報

PowerPoint 簡報 UI 設計 Android 專案目錄架構 Android 專案建立後會自動產生 3 個主要目錄 src:java 程式檔案 res: 資源 ( 文字 圖形 聲音檔案等 ) 與 UI 設定有關的 layout 檔 此目錄內檔案名稱只能為小寫字母 數字 _. gen:r.java 根據 res 目錄內容自動產生 不要去修改 R.java Android 中所有的資源檔案 ( 圖片 XML 等 ) 命名都必須使用英文小寫,

More information

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP:  ******************* * 关于 Java 测试试题 ****** ******************* * 关于 Java 测试试题 ******************* 問 1 运行下面的程序, 选出一个正确的运行结果 public class Sample { public static void main(string[] args) { int[] test = { 1, 2, 3, 4, 5 ; for(int i = 1 ; i System.out.print(test[i]);

More information

小应用 Magic8

小应用 Magic8 胡家威 计研135班 http://hujiaweibujidao.github.io/ 小应用 Magic8 Android 系统简介 Android 应用结构 Android 四大组件 Activity 生命周期 Android 资源管理 UI 组件和容器组件 内容概要 ( 上 ) Android 系统简介 Android 市场份额 Android 是如何诞生的? Android 之父 :Andy

More information

Microsoft PowerPoint - 05.Android 介面元件-RelativeLayout、Button、TextVeiw、EditText

Microsoft PowerPoint - 05.Android 介面元件-RelativeLayout、Button、TextVeiw、EditText 計劃名稱 : 104 年度教育部資通訊軟體創新人才推升推廣計畫跨校資源中心 : 雲端運算 ( 國立中山大學 ) 課程名稱 : 網路及平台服務 Part1- 課程教材 教材名稱 :Android 介面元件 -RelativeLayout Button TextVeiw EditText 國立高雄大學資訊工程學系張保榮教授 大綱 RelativeLayout 版面配置 Button 版面配置 TextView

More information

untitled

untitled JavaEE+Android - 6 1.5-2 JavaEE web MIS OA ERP BOSS Android Android Google Map office HTML CSS,java Android + SQL Sever JavaWeb JavaScript/AJAX jquery Java Oracle SSH SSH EJB+JBOSS Android + 1. 2. IDE

More information

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 月 3 日 1 1 INPUTOUTPUT 1 InputOutput 题目描述 用 cin 输入你的姓名 ( 没有空格 ) 和年龄 ( 整数 ), 并用 cout 输出 输入输出符合以下范例 输入 master 999 输出 I am master, 999 years old. 注意 "," 后面有一个空格,"." 结束,

More information

The Embedded computing platform

The Embedded computing platform Android User Interfaces Hsiao-Lung Chan, Ph.D. Dept Electrical Engineering Chang Gung University, Taiwan chanhl@maili.cgu.edu.tw Basic control components Text components TextView EditText Button compoents

More information

Microsoft PowerPoint - 04 界面编程.ppt [兼容模式]

Microsoft PowerPoint - 04 界面编程.ppt [兼容模式] 手机应用平台软件开发 4 界面编程 刘宁 Email:liuning2@mail.sysu.edu.cn UI 简介 UI(User Interface) 用户界面系统和用户之间进行交互和信息交换的媒介, 主要作用是实现信息内部形式与人类可接受形式之间的转换 人机交互实践中, 一个好的界面设计不仅让软件变得更加有个性和创意, 同时还能让软件的操作变得舒适 简单 自由, 充分体现软件的定位和特点 一个友好美观的界面会给人带来舒适的视觉享受,

More information

Microsoft Word 杨超-spinner实现省市县的三级联动.docx

Microsoft Word 杨超-spinner实现省市县的三级联动.docx Spinner 实现省市县的三级联动 1801210908- 杨超 下拉框 Spinner 控件 : 常用属性 属性 说明 android:prompt 下拉提示信息 android:spinnermode 下拉显示方法 android:entries 配置下拉框数据源 android:dropdownwidth 下拉框显示模式下的显示项宽度 常用方法 方法 说明 getdropdownwidth()

More information

RecyclerView and CardVew

RecyclerView and CardVew RecyclerView and CardView 建國科技大學資管系饒瑞佶 2017/10 V1 CardView CardView A CardView is a ViewGroup. Like any other ViewGroup, it can be added to youractivity or Fragment using a layout XML file. To create an

More information

03 开发入门.key

03 开发入门.key #3 手机应用开发入门 刘宁 Email:liuning2@mail.sysu.edu.cn 大纲» Android 基本概念» 开发包及 工具安装» 创建 HelloWorld» Android 程序设计基础 2 Android 开发基本概念» Activities» Intents» 视图与控件 ( 界 面元素 )» 异步调 用 ( 多线程 支持 )» 后台服务 3 Activities Android

More information

中 文 摘 要 智 慧 型 手 機 由 於 有 強 大 的 功 能, 以 及 優 渥 的 便 利 性, 還 能 與 網 路 保 持 隨 時 的 鏈 結 與 同 步 更 新, 因 此 深 受 廣 大 消 費 者 喜 愛, 當 然, 手 機 遊 戲 也 成 為 現 代 人 不 可 或 缺 的 娛 樂 之

中 文 摘 要 智 慧 型 手 機 由 於 有 強 大 的 功 能, 以 及 優 渥 的 便 利 性, 還 能 與 網 路 保 持 隨 時 的 鏈 結 與 同 步 更 新, 因 此 深 受 廣 大 消 費 者 喜 愛, 當 然, 手 機 遊 戲 也 成 為 現 代 人 不 可 或 缺 的 娛 樂 之 臺 北 市 大 安 高 級 工 業 職 業 學 校 資 訊 科 一 百 零 一 學 年 度 專 題 製 作 報 告 ------ 以 Android 製 作 ------ ----- 連 線 塔 防 遊 戲 ------ Tower defense game using Internet technology 班 級 : 資 訊 三 甲 組 別 : A9 組 組 員 : 葉 冠 麟 (9906129)

More information

Android Robert C.C. Huang Oscar F.Y. Liu Peter C.L. Hsieh 2011/03/21

Android Robert C.C. Huang Oscar F.Y. Liu Peter C.L. Hsieh 2011/03/21 Android Robert C.C. Huang Oscar F.Y. Liu Peter C.L. Hsieh 2011/03/21 Outlines for Today Future Planning Review System Architecture Dev. Tools & Making the First App Project Structure & File Details Application

More information

Android 基礎教學

Android 基礎教學 Android 基礎教學 吳柏翰 1 Outline Android 歷史起源 Android 優勢與市場未來趨勢 安裝 Android SDK 建立專案 模擬器的執行與操作 使用 Log 及 IDE 除錯工具 實機運作 2 Android 歷史起源 起源 隨著手機與網際網路結合, 上網普及化之後, 使用者對手機的功能有截然不同的需求 透過網際網路, 各種新的服務與應用應運而生, 使用者也希望手機平台能像電腦一樣,

More information

PowerPoint 演示文稿

PowerPoint 演示文稿 按钮对象 (button) 当 JavaScript 读到 标记中的 type 属性值为 button 时, 自动建立一个按钮对象, 并将该对象放到表单对象的 elements 数组当中 按钮对象包括 : 普通按钮 (button) 提交按钮 (submit) 重置按钮 (reset) 1. 使用按钮对象的格式 document.forms[ 索引值 ].elements[ 索引值

More information

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页 第 1 页共 32 页 crm Mobile V1.0 for IOS 用户手册 一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页 二 crm Mobile 界面介绍 : 第 3 页共 32 页 三 新建 (New) 功能使用说明 1 选择产品 第 4 页共 32 页 2 填写问题的简要描述和详细描述 第 5 页共

More information

Android 开发教程

Android 开发教程 封面 1 文件存取编程基础 文件 文件可以用来存储比使用引用更大数量的数据 Android 提供方法来读 写文件 只有本地文件可以被访问 优点 : 可以存储大容量的数据 缺点 : 文件更新或是格式改变可能会导致巨大的编程工作 文件操作 读文件 Context.openFileInput(String name) 打开一个与应用程序联系的私有文件输入流 当文件不存在时抛出 FileNotFoundException

More information

1

1 内 容 提 要 作 为 Google 开 发 的 全 新 开 源 手 机 平 台,Android 发 展 如 火 如 荼 本 书 通 过 大 量 代 码 秘 诀 全 面 详 尽 地 讲 述 了 Android 开 发 技 术 从 activity 和 intent 基 础 知 识 开 始, 到 线 程 服 务 broadcast receiver 以 及 alert 警 告 框, 再 到 用 户 界

More information

Microsoft Word - 第5章.doc

Microsoft Word - 第5章.doc 第 5 课 Android 基 础 控 件 详 解 Android 应 用 程 序 的 人 机 交 互 界 面 有 很 多 Android 控 件 组 成 几 乎 所 有 的 Android 都 会 涉 及 到 控 件 技 术, 如 文 本 框 编 辑 框 按 钮 列 表 等 控 件 这 些 在 Android 应 用 程 序 中 随 处 可 见, 本 课 将 对 Android 提 供 的 基 础

More information

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double

More information

图 6-1 主界面 MainActivity 界面对应的布局文件 (activity_main.xml) 如下所示 : <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="

图 6-1 主界面 MainActivity 界面对应的布局文件 (activity_main.xml) 如下所示 : <?xml version=1.0 encoding=utf-8?> <RelativeLayout xmlns:android= 第 6 章广播接收者 应用案例 案例 6-1 CallRecord( 通话记录 ) 一 案例描述 1 考核知识点 030006001: 广播接收者简介 030006002: 广播接收者的创建 2 练习目标 广播的静态注册和使用 使用广播处理处理事件 3 需求分析手机最重要的功能就是通话功能, 同样储存通话记录也是必不可少的 该案例使用广 播接收者自己实现通话记录的功能 包括呼出电话 已接来电 未接来电以及通话产生的

More information

目 錄 一 ANDROID 開發系統需求 作業系統 開發工具... 1 二 安裝 ANDROID 開發工具 安裝 JDK 使用 APT-GET 安裝 使用套件管理程式安裝... 9 三 ANDROID 程式撰寫... 1

目 錄 一 ANDROID 開發系統需求 作業系統 開發工具... 1 二 安裝 ANDROID 開發工具 安裝 JDK 使用 APT-GET 安裝 使用套件管理程式安裝... 9 三 ANDROID 程式撰寫... 1 Android On Linux 簡易安裝開發教學 Installing Google Android SDK 2.0.1 On Ubuntu 9.10 Desktop 目 錄 一 ANDROID 開發系統需求... 1 1. 作業系統... 1 2. 開發工具... 1 二 安裝 ANDROID 開發工具... 1 1. 安裝 JDK... 1 2. 使用 APT-GET 安裝... 2 3. 使用套件管理程式安裝...

More information

Microsoft Word - weather12 刷新按钮动画+搜索框+bug处理.docx

Microsoft Word - weather12 刷新按钮动画+搜索框+bug处理.docx 一 刷新按钮的动画效果 : 在刷新按钮的位置做两个按钮的布局, 一个是原来的静态图片, 一个是旋转的动画, 然 后控制这两个效果的显示和隐藏 ( 一 ) 刷新按钮的 style: 1. 在 app/src/main/res/values/ styles.xml 文件里添加一个 style: 2. 在 drawable 文件夹下新建一个 title_update_anim.xml, 添加如下内容 注

More information

Microsoft Word - 第1章 Android基本概念.docx

Microsoft Word - 第1章 Android基本概念.docx Android 系 统 下 Java 编 程 详 解 作 者 : 华 清 远 见 第 1 章 Android 基 本 概 念 本 章 简 介 本 章 主 要 介 绍 Android 基 本 概 念 方 面 的 内 容, 包 括 Android 平 台 特 性 Android 系 统 架 构 Android 开 发 框 架 和 Android 开 发 环 境 搭 建 1.1 Android 简 介 Android

More information

Microsoft Word - 第4章 3D相册.doc

Microsoft Word - 第4章 3D相册.doc 第 4 章 3D 相册 学习目标 u 掌握相册界面的开发, 实现相册的立体与倒影效果 在现实生活中, 我们浏览照片时, 不同的相册软件有不同的浏览效果 本章主要实现了一个 3D 效果的相册, 该相册中的图片可以循环滑动展示 4.1 3D 相册 任务综述 相册界面主要是展示一组图片的立体效果, 并显示每个图片的倒影, 左右滑动可以切换不同的图片到 界面的中间位置, 同时在图片下方显示当前图片的标题,

More information

教案模板4-2

教案模板4-2 移动终端开发技术 电子教案 第三单元 ListView 的功能和用法 章节名称 : 第二章 软件要美观 UI 开发的点点滴滴 所属专业 ( 教研室 ): 计算机软件技术 制定人 : 陈媛媛 合作人 : 制定时间 : 2018 年 2 月 日照职业技术学院 单元标题 ListView 的功能和用法 单元教学学时 在整体设计中的位置 4 课时 第 7 次 授课班级上课地点一体化教室 上课时间周月日第节

More information

建立Android新專案

建立Android新專案 Android 智 慧 型 手 機 程 式 設 計 Android WebService 建 國 科 技 大 學 資 管 系 饒 瑞 佶 2012/4 V1 2012/8 V2 2013/5 V3 2014/10 v4 提 醒 這 節 的 內 容 針 對 的 是 MS 的 Web Service 或 是 使 用 SOAP(Simple Object Access Protocol) 標 準 建 立

More information

新・解きながら学ぶJava

新・解きながら学ぶJava 481! 41, 74!= 40, 270 " 4 % 23, 25 %% 121 %c 425 %d 121 %o 121 %x 121 & 199 && 48 ' 81, 425 ( ) 14, 17 ( ) 128 ( ) 183 * 23 */ 3, 390 ++ 79 ++ 80 += 93 + 22 + 23 + 279 + 14 + 124 + 7, 148, 16 -- 79 --

More information

Microsoft Word - 02.目錄.doc

Microsoft Word - 02.目錄.doc 目錄 -1- 目錄 序 準備篇 一 使用說明... 0-2 二 標示說明... 0-6 三 注意事項... 0-7 第一類 Android 基礎知識 -UI 設計及語法應用 101. 整存整付計算機... 1-2 102. 電費計算機... 1-8 103. 點餐系統... 1-18 104. 計算 BMI 值... 1-23 105. MENU 功能選單... 1-36 106. 畫廊展示...

More information

任务实施 (1) 创建项目 图 3-1 欢迎界面 首先创建一个工程, 将其命名为 BoXueGu, 指定包名为 com.boxuegu (2) 导入界面图片将欢迎界面所需要的背景图片 launch_bg.png 导入到 drawable 文件夹中, 项目的 icon 图标 app_icon.png

任务实施 (1) 创建项目 图 3-1 欢迎界面 首先创建一个工程, 将其命名为 BoXueGu, 指定包名为 com.boxuegu (2) 导入界面图片将欢迎界面所需要的背景图片 launch_bg.png 导入到 drawable 文件夹中, 项目的 icon 图标 app_icon.png 第 3 章注册与登录模块 学习目标 掌握欢迎界面的开发, 能够独立制作欢迎界面 ; 掌握注册和登录模块的开发, 能够实现用户登录功能 博学谷项目的注册与登录模块主要用于创建用户账号, 管理用户信息 当用户注册成功后会跳转到登录界面, 用户登录后可以修改密码以及设置密保, 且只有设置过密保的账户才可以找回密码 本章将针对注册与登录模块进行详细讲解 3.1 欢迎界面 任务综述 在实际开发中, 开启应用程序时首先会呈现一个欢迎界面,

More information

内文-2.indd

内文-2.indd 客户端服务端音乐资源信息 : 1. 项目需求从本项目开始, 我们一起开发一个简单的在线音乐播放器, 它具有以下功能 (1) 程序启动时显示一个启动画面, 如图 1-1 所示 (2) 在程序主页面显示服务器上的歌曲列表, 包括歌手名与歌曲名, 单击列表条目可实现在线音乐播放, 单击 播放 暂停 上一曲 下一曲 按钮可实现对应的功能, 进度条可以显示歌曲播放进度, 如图 1-2 所示 图 1-1 程序启动画面

More information

Android线程和进程

Android线程和进程 Android 进程和线程 版权声明 华清远见教育集团版权所有 ; 未经华清远见明确许可, 不得为任何目的以任何形式复制或传播此文档的任何部分 ; 本文档包含的信息如有更改, 恕不另行通知 ; 华清远见教育集团保留所有权利 Android 进程和线程 在安装 Android 应用程序的时候,Android 会为每个程序分配一个 Linux 用户 ID, 并设置相应的权限, 这样其它应用程序就不能访问此应用程序所拥有的数据和资源了

More information

建模与图形思考

建模与图形思考 C03_c 基 於 軟 硬 整 合 觀 點 JNI: 从 C 调 用 Java 函 数 ( c) By 高 煥 堂 3 How-to: 基 於 軟 硬 整 合 觀 點 从 C 调 用 Java 函 数 如 果 控 制 点 摆 在 本 地 C 层, 就 会 常 常 1. 从 本 地 C 函 数 去 调 用 Java 函 数 ; 2. 从 本 地 C 函 数 去 存 取 Java 层 对 象 的 属 性

More information

Microsoft PowerPoint - 03 开发入门.ppt [兼容模式]

Microsoft PowerPoint - 03 开发入门.ppt [兼容模式] 手 机 应 用 平 台 软 件 开 发 3 开 发 入 门 刘 宁 Email:liuning2@mail.sysu.edu.cn 课 程 简 介 课 程 目 标 Android 开 发 准 备 工 作 开 发 包 及 工 具 安 装 创 建 HelloWorld Android 程 序 设 计 基 础 创 意 移 动 应 用 创 意 移 动 应 用 创 意 移 动 应 用 创 意 移 动 应 用

More information

Microsoft PowerPoint - chapter05.ppt

Microsoft PowerPoint - chapter05.ppt 第 5 章 Android 用户界面 本章学习目标 了解用户界面基础知识 掌握几个常用界面控件使用方法 掌握界面布局基本方法 掌握菜单设计基本方法 了解 Android 界面框架调用界面控件的事件处理函数对事件进行处理的方法 Android UI 组件概述 应用程序的好坏, 主要有三个元素决定 界面 功能 性能 界面给用户的第一感觉至关重要 UI 的设计与控制是程序开发核心内容之一 Android

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Java application Java main applet Web applet Runnable Thread CPU Thread 1 Thread 2 Thread 3 CUP Thread 1 Thread 2 Thread 3 ,,. (new) Thread (runnable) start( ) CPU (running) run ( ) blocked CPU sleep(

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d

More information

Microsoft Word zw

Microsoft Word zw 第 1 章 Android 概述 学习目标 : Android Android Android Studio Android Android APK 1.1 1. 智能手机的定义 Smartphone 2. 智能手机的发展 1973 4 3 PC IBM 1994 IBM Simon PDA PDA Zaurus OS 1996 Nokia 9000 Communicator Nokia 9000

More information

Database_001

Database_001 作者 : 林致宇日期 :2011/10/26 主要參考來源 : http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applicat ions/ 問題 : 如在存取一個已經建立好的資料庫? 解答 : 有一些應用程式會需要讀取已經建立好的資料庫, 例如一個試題測驗應用程式, 裡面的試題可能已經於電腦上, 使用任何的

More information

Microsoft PowerPoint - ch6 [相容模式]

Microsoft PowerPoint - ch6 [相容模式] UiBinder wzyang@asia.edu.tw UiBinder Java GWT UiBinder XML UI i18n (widget) 1 2 UiBinder HelloWidget.ui.xml: UI HelloWidgetBinder HelloWidget.java XML UI Owner class ( Composite ) UI XML UiBinder: Owner

More information

Microsoft Word - 01.DOC

Microsoft Word - 01.DOC 第 1 章 JavaScript 简 介 JavaScript 是 NetScape 公 司 为 Navigator 浏 览 器 开 发 的, 是 写 在 HTML 文 件 中 的 一 种 脚 本 语 言, 能 实 现 网 页 内 容 的 交 互 显 示 当 用 户 在 客 户 端 显 示 该 网 页 时, 浏 览 器 就 会 执 行 JavaScript 程 序, 用 户 通 过 交 互 式 的

More information

1. 2. Flex Adobe 3.

1. 2. Flex Adobe 3. 1. 2. Flex Adobe 3. Flex Adobe Flex Flex Web Flex Flex Flex Adobe Flash Player 9 /rich Internet applications/ria Flex 1. 2. 3. 4. 5. 6. SWF Flash Player Flex 1. Flex framework Adobe Flex 2 framework RIA

More information

// HDevelopTemplateWPF projects located under %HALCONEXAMPLES%\c# using System; using HalconDotNet; public partial class HDevelopExport public HTuple

// HDevelopTemplateWPF projects located under %HALCONEXAMPLES%\c# using System; using HalconDotNet; public partial class HDevelopExport public HTuple halcon 与 C# 混合编程之 Halcon 代码调用 写在前面 完成 halcon 与 C# 混合编程的环境配置后, 进行界面布局设计构思每一个按钮所需要实现 的功能, 将 Halcon 导出的代码复制至相应的 C# 模块下即可 halcon 源程序 : dev_open_window(0, 0, 512, 512, 'black', WindowHandle) read_image (Image,

More information

Android + NFC

Android + NFC Android + NFC 建國科技大學資管系饒瑞佶 2017/3 v1 讀取 Tag UUID Android 2.3.3 (API Level 10) 才有支援完整的 NFC 功能 只要 NFC 相容都讀的到 (NFC 或 Mifare) 建立新專案修改 AndroidManifest.xml 加入 , 如果有 NFC Tag 進入感測範圍, 本 App 也會變成可處理的

More information

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入 100 年 特 種 考 試 地 方 政 府 公 務 人 員 考 試 試 題 等 別 : 三 等 考 試 類 科 : 資 訊 處 理 科 目 : 系 統 分 析 與 設 計 一 請 參 考 下 列 旅 館 管 理 系 統 的 使 用 案 例 圖 (Use Case Diagram) 撰 寫 預 約 房 間 的 使 用 案 例 規 格 書 (Use Case Specification), 繪 出 入

More information

ContextMenu

ContextMenu 作者 : 林致宇 日期 :2012/1/20 問題 : 如何建立 ContextMenu? 解答 : 什麼是 ContextMenu 呢? 下面兩張圖是 ContextMenu 的範例, 紅色框線中的選單即所謂的 ContextMenu, 可以視為 選單列表, 例如在左圖的 ContextMenu 中有兩個選項 : Action 1 與 Action 2, 按下 Action 1 可執行某些動作,

More information

<4D6963726F736F667420576F7264202D20B5DA33D5C220B3CCD0F2C9E8BCC6BBF9B4A12E646F6378>

<4D6963726F736F667420576F7264202D20B5DA33D5C220B3CCD0F2C9E8BCC6BBF9B4A12E646F6378> Android 应 用 程 序 开 发 与 典 型 案 例 作 者 : 华 清 远 见 第 3 章 程 序 设 计 基 础 本 章 简 介 在 上 一 章 的 学 习 中, 主 要 了 解 了 Eclipse+ADT 的 开 发 流 程, 对 其 有 了 初 步 的 认 识 和 了 解 对 初 学 者 来 说, 这 一 章 的 内 容 比 较 烦 琐, 但 是 又 必 须 掌 握, 这 也 是 进

More information

Microsoft Word - Android App开发从入门到精通.doc

Microsoft Word - Android App开发从入门到精通.doc 第 2 章 Android 控件 本章主要介绍 Android 中常用的控件及其使用方法,Android SDK 本身给我们提供大量的 UI 控件, 合理熟练地使用这些控件才能做出优美的界面 有时候 Android 自带的控件不一定能满足业务需求, 所以本章还会介绍自定义控件 2.1 View 介绍 在 Android 开发中,Android 的 UI 界面都是由 View 及其派生类组合而成的 View

More information

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 -> 目录 1 大概思路... 1 2 创建 WebAPI... 1 3 创建 CrossMainController 并编写... 1 4 Nuget 安装 microsoft.aspnet.webapi.cors... 4 5 跨域设置路由... 4 6 编写 Jquery EasyUI 界面... 5 7 运行效果... 7 8 总结... 7 1 1 大概思路 创建 WebAPI 创建 CrossMainController

More information

untitled

untitled 1 行 行 行 行.NET 行 行 類 來 行 行 Thread 類 行 System.Threading 來 類 Thread 類 (1) public Thread(ThreadStart start ); Name 行 IsAlive 行 行狀 Start 行 行 Suspend 行 Resume 行 行 Thread 類 (2) Sleep 行 CurrentThread 行 ThreadStart

More information

可 Web 编程的NativeUI 设计与实现

可 Web 编程的NativeUI  设计与实现 可 Web 编程的 NativeUI 设计与实现 张袁炜 zhangyuanwei@baidu.com 欢迎转岗简历请发 About Me @ 张袁炜 直达号 网址导航 百度 音乐 前端 Node.js Android Arduino RaspberryPI https://github.com/zhangyuanwei Outline 一个 Hybrid App 的进化史 Native UI 实现原理

More information

版权声明

版权声明 大 话 企 业 级 Android 开 发 第 九 部 分 本 教 程 说 明 及 版 权 声 明 大 话 企 业 级 Android 开 发 是 国 士 工 作 室 为 了 方 便 中 国 Android 开 发 者, 推 动 Android 企 业 级 应 用 开 发, 特 投 入 大 量 心 血 撰 写 的 书 籍, 并 在 网 络 上 免 费 发 布, 希 望 为 移 动 互 联 网 和 智

More information

_banneradview.settest(true); _banneradview.setuserkeywords("swimming"); _banneradview.setusercategories("1,3,4"); _banneradview.setusergender(jdbanner

_banneradview.settest(true); _banneradview.setuserkeywords(swimming); _banneradview.setusercategories(1,3,4); _banneradview.setusergender(jdbanner 京东 APP 联盟 SDK Android 版接口说明文档 1.0 1. 嵌入 SDK 1.1 添加 SDK Android Studio 环境 : 菜单 New->New Module->Import.jar or.aar package, 然后选中 App 联盟 SDK 所带的 jar 文件 Eclipse+ADT 环境 : 将 App 联盟 SDK 所带的 jar 文件拷贝到 libs/ 目录下

More information

使用 Eclipse 开发 Java EE 应用 (Web 应用 ) 这里以开发一个简单的 Web 应用为例, 介绍使用 Eclipse 开发 Java EE 应用的一般步 骤 此处使用的 Eclipse 是 Eclipse IDE for Java EE Developers; 如果是使用的其他

使用 Eclipse 开发 Java EE 应用 (Web 应用 ) 这里以开发一个简单的 Web 应用为例, 介绍使用 Eclipse 开发 Java EE 应用的一般步 骤 此处使用的 Eclipse 是 Eclipse IDE for Java EE Developers; 如果是使用的其他 使用 Eclipse 开发 Java EE 应用 (Web 应用 ) 这里以开发一个简单的 Web 应用为例, 介绍使用 Eclipse 开发 Java EE 应用的一般步 骤 此处使用的 Eclipse 是 Eclipse IDE for Java EE Developers; 如果是使用的其他 Eclipse 插件 ( 比如 MyEclipse 插件 ), 其开发方式和步骤可能略有差异和不同 在该例中,

More information

Microsoft Word - Hibernate与Struts2和Spring组合指导.doc

Microsoft Word - Hibernate与Struts2和Spring组合指导.doc 1.1 组合 Hibernate 与 Spring 1. 在 Eclipse 中, 新建一个 Web project 2. 给该项目增加 Hibernate 开发能力, 增加 Hibernate 相关类库到当前项目的 Build Path, 同时也提供了 hibernate.cfg.xml 这个配置文件 3. 给该项目增加 Spring 开发能力, 增加 spring 相关类库到当前项目的 Build

More information

Chapter 10

Chapter 10 Chapter 10 多媒體程式開發 Widget Widget 簡介 android.widget 套件包含了許多視覺性的 UI 元素, 可用來將操作界面展示在應用程式畫面上 要熟悉 Android 多媒體程式的開發, 必須從 widget 套件著手, 因此本章所舉的範例, 便是以 android.widget 套件的應用為中心 Gallery 簡介 Gallery 是一個水平的清單, 移動清單時,

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc Java C++ Pascal C# C# if if if for while do while foreach while do while C# 3.1.1 ; 3-1 ischeck Test() While ischeck while static bool ischeck = true; public static void Test() while (ischeck) ; ischeck

More information

无类继承.key

无类继承.key 无类继承 JavaScript 面向对象的根基 周爱 民 / aimingoo aiming@gmail.com https://aimingoo.github.io https://github.com/aimingoo rand = new Person("Rand McKinnon",... https://docs.oracle.com/cd/e19957-01/816-6408-10/object.htm#1193255

More information

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 Java V1.0.1 2007 4 10 1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 6.2.10 6.3..10 6.4 11 7.12 7.1

More information

Microsoft Word - 1 扉页

Microsoft Word - 1 扉页 普通高等教育应用型规划教材 计算机类 Android 程序开发入门教程 俞成海宋瑾钰 舒挺郭家军 编著 北京 内容简介 本书共分 9 章 第 1 章讲述 Android 起源 概述 环境搭建及 Android Studio 的一些使用技巧 ; 第 2 章讲述 Android 程序的基本构成 生命周期及程序中的几大常用布局 ; 第 3 章介绍 Android 中的基础通用控件, 包括常用的文本控件 编辑控件

More information

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 复习 Java 包 创建包 : package 语句, 包结构与目录结构一致 使用包 : import restaurant/ - people/ - Cook.class - Waiter.class - tools/ - Fork.class

More information

Microsoft Word - Broker.doc

Microsoft Word - Broker.doc Broker 模式 采用 broker 模式对分布式计算进行简单模拟 系统在一个进程内模拟分布式环境, 因此不涉及网络编程和进程间通信,Broker 通过本地函数调用的方式实现 request 和 response 的转发 采用 broker 模式对分布式计算进行简单的模拟, 要求如下 : 设计四个 server, 一个 server 接收两个整数, 求和并返回结果, 一个 server 接收两个整数,

More information

第6讲

第6讲 UI 及 图 形 应 用 开 发 技 术 哈 尔 滨 工 业 大 学 软 件 学 院 唐 好 选 Email:tanghx@hit.edu.cn 主 要 内 容 Android UI 布 局 图 形 控 件 常 用 的 XML 属 性 图 形 界 面 中 常 用 的 控 件 元 素 菜 单 对 话 框 Android 的 UI 布 局 为 了 适 应 各 式 各 样 的 界 面 风 格,Android

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Fortran Algol Pascal Modula-2 BCPL C Simula SmallTalk C++ Ada Java C# C Fortran 5.1 message A B 5.2 1 class Vehicle subclass Car object mycar public class Vehicle extends Object{ public int WheelNum

More information

<4D F736F F D20B5DA35D5C220D3C3BBA7BDE7C3E6BFAAB7A22E646F6378>

<4D F736F F D20B5DA35D5C220D3C3BBA7BDE7C3E6BFAAB7A22E646F6378> Android 应用程序开发与典型案例 作者 : 华清远见 第 5 章用户界面开发 本章简介 在上一章的学习中, 主要了解了 Android 系统的进程优先级排序 不同优先级 进程之间的变化方式,Android 系统的 4 大基本组件及其用途,Activity 的生命周期 中各个状态及状态间的变化关系 Android 应用程序的调试方法和工具 在此基础 上, 本章将对 Android 程序界面开发的学习,

More information

课程代码:?

课程代码:? Android 应用开发 课程实验教学大纲 课程名称 :Android 应用开发课程代码 :10011207 课程学时 : 128 学时 ( 实验 64 学时 ) 课程学分 :4 适用专业 : 计算机科学与技术 一 验证性实验 课程教学中验证原理 算法 技术 效果等 实验一 : 搭建 Android 平台和创建 HelloWorld(2 学时 ) 实验类型 验证性 本次实验的目的是让大家熟悉搭建智能手机开发平台的过程,

More information

DU Ad Platform_SDK 安卓接入指南 DU Ad Platform_SDK for Android 接入手册 ( 触发式广告 ) DUAd_SDK_Trigger v1.0 百度在线网络技术 ( 北京 ) 有限公司 百度在线网络技术 ( 北京 ) 有限公司 - 1 -

DU Ad Platform_SDK 安卓接入指南 DU Ad Platform_SDK for Android 接入手册 ( 触发式广告 ) DUAd_SDK_Trigger v1.0 百度在线网络技术 ( 北京 ) 有限公司 百度在线网络技术 ( 北京 ) 有限公司 - 1 - DU Ad Platform_SDK for Android 接入手册 ( 触发式广告 ) DUAd_SDK_Trigger v1.0-1 - 目录 1. 获取身份... 1 2. 加载与配置... 2 2.1 加载 SDK 文件... 2 2.2 配置 AndroidManifest.xml... 2 2.3 混淆代码... 3 3. 初始化... 4 4. 功能使用... 4 第 1 页共 1

More information

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc 本章学习目标 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 配置视图解析器 @RequestMapping 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc 和 Struts2 都属于表现层的框架, 它是 Spring 框架的一部分, 我们可 以从 Spring 的整体结构中看得出来 :

More information

Microsoft PowerPoint - 07.Android 介面元件-TableLayout、Toast、AlertDialog

Microsoft PowerPoint - 07.Android 介面元件-TableLayout、Toast、AlertDialog 計劃名稱 : 104 年度教育部資通訊軟體創新人才推升推廣計畫跨校資源中心 : 雲端運算 ( 國立中山大學 ) 課程名稱 : 網路及平台服務 Part1- 課程教材 教材名稱 :Android 介面元件 -TableLayout Toast AlertDialog 國立高雄大學資訊工程學系張保榮教授 大綱 TableLayout 版面配置 Toast 版面配置 AlertDialog 版面配置 TableLayout

More information

XXX说明书

XXX说明书 实验 1 Android SDK 开发环境的安装及配置 1.1 实验目的 掌握 Java SDK 和 Android SDK 开发环境的安装和配置 1.2 实验内容 Java SDK 的安装和环境变量的配置 Eclipse 的安装和配置 Android SDK 的安装和环境变量的配置 Eclipse 插件 ADT 的安装和配置 Android 模拟器的配置 1.3 实验步骤 1.Java SDK 的安装和环境变量的配置

More information

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

KillTest 质量更高 服务更好 学习资料   半年免费更新服务 KillTest 质量更高 服务更好 学习资料 http://www.killtest.cn 半年免费更新服务 Exam : 310-065Big5 Title : Sun Certified Programmer for the Java 2 Platform, SE 6.0 Version : Demo 1 / 14 1. 35. String #name = "Jane Doe"; 36. int

More information

第四章 102 图 4唱16 基于图像渲染的理论基础 三张拍摄图像以及它们投影到球面上生成的球面图像 拼图的圆心是相同的 而拼图是由球面图像上的弧线图像组成的 因此我 们称之为同心球拼图 如图 4唱18 所示 这些拼图中半径最大的是圆 Ck 最小的是圆 C0 设圆 Ck 的半径为 r 虚拟相机水平视域为 θ 有 r R sin θ 2 4畅11 由此可见 构造同心球拼图的过程实际上就是对投影图像中的弧线图像

More information

目 錄 版 次 變 更 記 錄... 2 原 始 程 式 碼 類 型 之 使 用 手 冊... 3 一 安 裝 軟 體 套 件 事 前 準 備... 3 二 編 譯 流 程 說 明... 25 1

目 錄 版 次 變 更 記 錄... 2 原 始 程 式 碼 類 型 之 使 用 手 冊... 3 一 安 裝 軟 體 套 件 事 前 準 備... 3 二 編 譯 流 程 說 明... 25 1 科 技 部 自 由 軟 體 專 案 原 始 程 式 碼 使 用 手 冊 Source Code Manual of NSC Open Source Project 可 信 賴 的 App 安 全 應 用 框 架 -App 應 用 服 務 可 移 轉 性 驗 證 Trusted App Framework -Transferability Verification on App MOST 102-2218-E-011-012

More information

上海市教育委员会文件

上海市教育委员会文件 上 海 高 校 市 级 精 品 课 程 申 报 表 ( 2016 年 度 ) 学 校 名 称 上 海 师 范 大 学 课 程 名 称 Android 应 用 程 序 设 计 课 程 类 型 理 论 课 ( 不 含 实 践 ) 理 论 课 ( 含 实 践 ) 实 验 ( 践 ) 课 所 属 院 系 教 研 室 信 息 与 机 电 学 院 计 算 机 科 学 与 技 术 系 课 程 负 责 人 李 鲁

More information