使用者人机界面 - Google Android SDK开发范例大全


用户人机界 面 Google Android SDK 开发范 例大全 36 3-1 更改与 显示文字标 签 —TextView 标签的 使用 范例说明 前一章写了 Hello World 之后,一 直觉得没有写半行 代码对不起自己 ,所以在本章人机 界面 一开始 , 则 延续 Hello Wolrd 的气势 , 进 行与 TextView 文字标 签的第一次 接触。 在 此 范例 中, 将会在 Layout中创建 TextView 对象, 并 学 会定义 res/values/strings.xml 里的字 符串常数, 最 后通过 TextView 的setText 方法, 在预加载程 序之初,更改 TextView 文字。 运行结果 ▲图3-1 认识 TextView.setText 更改默认 Layout 里定义 的文本字符串 范例程序 src/irdc.ex03_01/EX03_01.javasrc/irdc.ex03_01/EX03_01.javasrc/irdc.ex03_01/EX03_01.javasrc/irdc.ex03_01/EX03_01.java 主程序 示范以 setText 方法, 输出 String 类型的 字符串变量 。 packageirdc.ex03_01; importandroid.app.Activity; importandroid.os.Bundle; /*必须引用 widget.TextView才能在程 序里声明 TextView对象 */ importandroid.widget.TextView; publicclassEX03_01extendsActivity { 第3章使用者 人机接口 37 /*必须引用 widget.TextView 才能在程 序里声明 TextView对象 */ private TextView mTextView01; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* 载入 main.xml Layout,此时 myTextView01:text为str_1 */ setContentView(R.layout.main); /* 使用 findViewBtId函数,利用 ID找到该 TextView对象 */ mTextView01mTextView01mTextView01mTextView01====(TextView)(TextView)(TextView)(TextView)findViewById(R.id.myTextView01);findViewById(R.id.myTextView01);findViewById(R.id.myTextView01);findViewById(R.id.myTextView01); String str_2 = "欢迎来到 Android 的TextView世界 ..."; mTextView01.setText(str_2);mTextView01.setText(str_2);mTextView01.setText(str_2);mTextView01.setText(str_2); } } res/layout/main.xmlres/layout/main.xmlres/layout/main.xmlres/layout/main.xml 以android:id 命名 TextView 的ID 为mTextView01;在较旧 的版本写法与 1.0 的不同, 请特 别留意 。 Google Android SDK 开发范 例大全 38 扩展学习 TextView 里的 setText 方法支 持以下多态 构造方法: publicfinalvoidsetText(CharSequencetext) publicfinalvoidsetText(intresid) publicvoidsetText(CharSequencetext,TextView.BufferTypetype) publicfinalvoidsetText(intresid,TextView.BufferTypetype) publicfinalvoidsetText(char[]text,intstart,intlen) 在此, 以最后 setText(char[] text, int start, int len) 为例, 第一个参数为 char数组作 为输出依 据, 第二个 参数为从哪 一个元素索 引开始选取 ,第 三个参数则 为要取出多 少个元素, 请看 以 下的例 子: charchar_1[]=newchar[5]; char_1[0]='D'; char_1[1]='a'; char_1[2]='v'; char_1[3]='i'; char_1[4]='d'; mTextView01.setText(char_1,1,3); 如上述 程序所示, 输 出的结果是 “avi”, 因为从第 1个元素 索引开始, 共取 3个元素 ; 最 后 则要提 醒你, TextView.setTextView不支持 HTMLTAG的输出 ,所以即便 写成这样: mTextView01.setText("戴维的博 客"); 实际输 出时, 也 就 是纯文本而 已, 并 不 会作 HTMLTAG的转换 。 但 若撇开 HTMLTAG之外 (如 “<”开头的 标记),在 TextView 里加上了 android:autoLink="all",那么 正文中若有 网 址( http://),是 可以被显示 的,以下这 个范例就交 给你自己实 现看看。 第3章使用者 人机接口 39 3-2 更改手 机窗口画面 底色 —drawable 定义颜 色常数的方 法 范例说明 在 之 前的 范 例 运 行结 果 , 窗口 的底 色 一 律 是 “深黑色 ”,这是SDK 默认的 颜色, 要 更改 Activity 里的窗 口底色有许 多方法, 最 简单的方 法就是将颜 色色码事先 定义在 drawable 当中, 当 程 序 onCreate 创建的 同时,加载 预先定义的 画面颜色。 此范例 程序的设计 方式是在 drawable 里指定 Layout的背景 色( BackGround)为白 色,但这 里的 “白色 ”(颜色 色码为 #FFFFFFFF) 预先定 义在 drawable 当中, 当 程序运行时 ,背 景 就 会变为 白色。 这是指定 Activity Layout背景颜色最简单的方法,在范例最末,则 将示范如何创建色 彩板 (color table) ,让 Android 手机程 序可以像使 用 “常数 ”般直接 取用, 并反应在 应用程序 的 运行阶 段。 运行结果 ▲图3-2 使用 drawable 设置颜色常 数,应用 于程序运行时的 结果 Google Android SDK 开发范 例大全 40 范例程序 src/irdc.ex03_02/EX03_02.javasrc/irdc.ex03_02/EX03_02.javasrc/irdc.ex03_02/EX03_02.javasrc/irdc.ex03_02/EX03_02.java 程序继承自 Activity 类,并在重写 onCreate 创建之初 ,直接显示 R.layout.main(main.xml) 这个页 面安排的布 局配置。 packageirdc.ex03_02; importandroid.app.Activity; importandroid.os.Bundle; publicpublicpublicpublicclassclassclassclassEX03_02EX03_02EX03_02EX03_02extendsextendsextendsextendsActivityActivityActivityActivity { /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);setContentView(R.layout.main);setContentView(R.layout.main);setContentView(R.layout.main); } } res/layout/main.xmlres/layout/main.xmlres/layout/main.xmlres/layout/main.xml 在页面 布局上,使 用了 2个TextView 对象, 以及 2个EditText 对象, 关键在于 android: background="@drawable/white" 让程序 背景变成了 白色,而 android:textColor="@drawable/ darkgray" 将TextView 里的文字颜色 ( textColor)设为灰色, 当中 “@drawable/white”及 “@drawable/darkgray”的写 法 则 是 参 考 事 先 于 drawable 里定 义好的颜色常数,将在 res/values/color.xml 里看见 颜色的定义 描述。 扩展学习 事先将定义好的颜 色代码( color code)以 drawable 的名称( name)存放于 resources 当中, 这是开发 Android 程序的 好习惯,正 如同字符串 常数一样, 颜色也是 可以事先定 义好的。 在 本范例 中学会了使用 drawable 的resource的定义 方法: color_value 定义好的 drawable name 常数, 必 须 存放于 res/values 下面, 作 为 资源取用, 但 定义 好的背 景 颜色并非 只能当作是 “默认 ”颜色声明 使用,在程序的事 件里,是可以通 过程序来更改的, 如以下 程序所示: Resources resources = getBaseContext().getResources(); Drawable HippoDrawable = resources.getDrawable(R.drawable.white); Google Android SDK 开发范 例大全 42 TextViewtv=(TextView)findViewByID(R.id.text); tv.setBackground(HippoDrawable); 第3章使用者 人机接口 43 3-3 更改 TextView 文字颜 色 —引用 Drawable 颜色常 数及背景色 范例说明 上一个范例通过 Drawable 来定义颜色常数, 但实际设计中最常用的方法,则是 使用程序控 制TextView 或其它 对象的背景 色( setBackgroundDrawable 方法) ,如判断对 象被点击时 的 背景色 亮起、当失 去焦点时, 又恢复成原 来的背景色 等等。 以下的范例,将扩展前一个范例的实现, 预先 在 Layout当中设计好两个 TextView,并在 onCreate 同时, 通过两种程 序描述方法 ,实时更改 原来 Layout里TextView 的背景 色以及文 字颜色 ,最后学会 使用 Android 默认的 颜色常数( graphics.Color)来更 改文字的前 景色。 运行结果 ▲图3-3 通过 setBackgroundDrawable 方法更改 TextView 的背景 色以及 graphics.Color 更改前景 色 范例程序 src/irdc.ex03_03/EX03_03.javasrc/irdc.ex03_03/EX03_03.javasrc/irdc.ex03_03/EX03_03.javasrc/irdc.ex03_03/EX03_03.java 程序里 新建两个类 成员变量: mTextView01 与mTextView02,这两 个变量在 onCreate 之初, 以findViewById 方法使 之初始化为 layout(main.xml)里的 TextView 对象。 在当中使用了 Resource类以及 Drawable 类,分 别创建了 resources 对象以及 HippoDrawable 对象, 并将前 一个范例中所创建的R.drawable.white 以getDrawable 方法加载,最后则调用了 setBackgroundDrawable 来更改 mTextView01 的文字 底纹。 更改 TextView 里的文 字, 则 使 用 了setText 方法。 Google Android SDK 开发范 例大全 44 在mTextView02 当中,使 用了 graphics.Color 里的颜色 常数,接着,再利用 setTextColor 更 改文字 的前景色。 packageirdc.ex03_03; importandroid.app.Activity; importandroid.content.res.Resources; importandroid.graphics.Color; importandroid.graphics.drawable.Drawable; importandroid.os.Bundle; importandroid.widget.TextView; publicclassEX03_03extendsActivity { privateTextViewmTextView01; privateTextViewmTextView02; /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTextView01=(TextView)findViewById(R.id.myTextView01); mTextView01.setText("我是应 用 Drawable背景色的戴维文 本。 "); ResourcesResourcesResourcesResourcesresourcesresourcesresourcesresources====getBaseContext().getResources();getBaseContext().getResources();getBaseContext().getResources();getBaseContext().getResources(); DrawableDrawableDrawableDrawableHippoDrawableHippoDrawableHippoDrawableHippoDrawable====resources.getDrawable(R.drawable.white);resources.getDrawable(R.drawable.white);resources.getDrawable(R.drawable.white);resources.getDrawable(R.drawable.white); mTextView01.setBackgroundDrawable(HippoDrawable);mTextView01.setBackgroundDrawable(HippoDrawable);mTextView01.setBackgroundDrawable(HippoDrawable);mTextView01.setBackgroundDrawable(HippoDrawable); mTextView02=(TextView)findViewById(R.id.myTextView02); /*下使 用 Color.MAGENTA指定文本的颜 色为紫红 色 */ mTextView02.setTextColor(Color.MAGENTA);mTextView02.setTextColor(Color.MAGENTA);mTextView02.setTextColor(Color.MAGENTA);mTextView02.setTextColor(Color.MAGENTA); } } 扩展学习 Resourcesresources=getBaseContext().getResources(); DrawableHippoDrawable=resources.getDrawable(R.drawable.white); 上述这 2行代码 ,在前一版 本中的写法 是这样的: Resources.resources=getDrawable(R.drawable.solid_red); DrawableHippoDrawable=resources.getDrawable(R.drawable.white); 第3章使用者 人机接口 45 但是在 1.0 之后的版 本, Resources 不再支持 直接使用 .getDrawable 方法直接 取用 drawable, 而必须 先取得基类的 Context 才行。 此外,在 程序里使用了 Color.MAGENTA 让TextView 里的文字 变成了粉红色,事 实上,在 Android里还有 以下 12 种常见 的颜色: Color.BLACK Color.BLUE Color.CYAN Color.DKGRAY Color.GRAY Color.GREEN Color.LTGRAY Color.MAGENTA Color.RED Color.TRANSPARENT Color.WHITE Color.YELLOW 这些颜 色常数是定 义在 android.graphics.Color 里的: 类型 常数 值 色码 int BLACK-16777216 0xff000000 int BLUE-16776961 0xff0000ff int CYAN-16711681 0xff00ffff int DKGRAY-12303292 0xff444444 int GRAY-7829368 0xff888888 int GREEN-16711936 0xff00ff00 int LTGRAY-3355444 0xffcccccc int MAGENTA-65281 0xffff00ff int RED-65536 0xffff0000 int TRANSPARENT 0 0x00000000 int WHITE-1 0xffffffff int YELLOW-256 0xffffff00 Google Android SDK 开发范 例大全 46 3-4 置换 TextView 文字 —CharSequence 数据类 型与 Resource ID应用 范例说明 从一开始自 Layout里通过 Resource 初始化 TextView 的文字,到程序中 动态更改 TextView 文字, 但 要 如何在代 码里取得 Resource的字符 串呢?在 Android里, 确 实 是有些方法 可以 直 接以 R.string.*直接转换 ID 为String,不过,这样的数据类型转换是非常规甚至是不妥的, 正确的 方法是利用 Context.getString 方法来 取得存放在 global 里的 Resource ID。 以下 这 个 范 例将示范 如何在程序运行时 ( runtime),通过 CharSequence依据 Resource ID 取 出 字 符串 , 并正确 更改 TextView 的文字 。 运行结果 ▲图3-4 通过 java.lang.CharSequenc e 这个 Interface 来取得存放在 global 里的 Resource ID 范例程序 src/irdc.ex03_04/EX03_04.javasrc/irdc.ex03_04/EX03_04.javasrc/irdc.ex03_04/EX03_04.javasrc/irdc.ex03_04/EX03_04.java 主程序的差异主要是在更改 mTextView02 的文字时( setText 方法),合并了 str_3 与str_2 这两个 不同对象, 由于 setText 方法同 时支持 CharSequence与String 类型的 参数,故在 此示 范不同 数据类型的 字符串进行 同步输出。 packageirdc.ex03_04; importandroid.app.Activity; importandroid.os.Bundle; importandroid.widget.TextView; 第3章使用者 人机接口 47 publicclassEX03_04extendsActivity { privateTextViewmTextView02; /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTextView02=(TextView)findViewById(R.id.myTextView02); CharSequenceCharSequenceCharSequenceCharSequencestr_2str_2str_2str_2====getString(R.string.str_2);getString(R.string.str_2);getString(R.string.str_2);getString(R.string.str_2); Stringstr_3="我是程序 里调用 Resource的"; mTextView02.setText(str_3mTextView02.setText(str_3mTextView02.setText(str_3mTextView02.setText(str_3++++str_2);str_2);str_2);str_2); } } res/layout/main.xmlres/layout/main.xmlres/layout/main.xmlres/layout/main.xml 为了作为 对比,在 main.xml 里创建了 两个 TextView,并采 LinearLayout 的方式配 置,一上 一下,在 运行结果中 id 为myTextView01 的TextView 并没有任 何文字的更改,维 持一开始 的str_1(参考字符串常数 里的文字),但在程序运行后, id 为myTextView02 的TextView 则作了 文字的实时 更改。 扩展学习 虽然在 values/strings.xml 里定义了默认的字 符串常数,需留意若遭遇如 “?”、“'”、“\” 等符号 时,必须使 用转义字符 ( \),如 下: \? \' \\ 3-5 取得手 机屏幕大小 —DisplayMetrics 取得画 面宽高的方 法 范例说明 在开发 手机应用程 序时, 除 了 底层对 API 的掌握 度之外, 最 重 要的仍是对 屏幕分辨率 的概 念, 因各家 手机厂商所 采用的屏幕 尺寸不同, user UI 接口呈 现及布局自 然也各异。 尽管 Android可设置 为随着窗口 大小调整缩 放比例,但 即便如此, 手机程序 设计人员还 是 必 须知道 手机屏幕的 边界, 以 避免缩 放造成的布 局 ( Layout) 变 形问题 。 这 个范例非常 的简 短, 只需几 行程序即可 取得手机的 分辨率,当 中的关键则是 DisplayMetrics 类的应 用。 第3章使用者 人机接口 49 运行结果 ▲图3-5 取得 Android 手机的 实际屏幕分辨率 范例程序 src/irdc.ex03_05/EX03_05.javasrc/irdc.ex03_05/EX03_05.javasrc/irdc.ex03_05/EX03_05.javasrc/irdc.ex03_05/EX03_05.java 在android.util 底下的 DisplayMetrics 对象 ,记录了 一些常用的 信息 ,包含了 显示信息、 大 小、 维度 、 字 体 等 等 ;在使 用 时 ,请记 得 引 用 android.util.DisplayMetrics 。值 得 一 提 的 是 DisplayMetrics 对象里的 widthPixels 及heightPixels 字段为 整数类型, 在 以下的程 序当中, 并 没有对 其作字符串 类型的转换 ,因为字符 串连接运算 符的缘故, 所以输出 strOpt 为 字 符串 。 package irdc.ex03_05; import android.app.Activity; import android.os.Bundle; import android.util.DisplayMetrics; import android.widget.TextView; public class EX03_05 extends Activity { private TextView mTextView01; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /* 必须引用 android.util.DisplayMetrics */ DisplayMetricsDisplayMetricsDisplayMetricsDisplayMetrics dmdmdmdm ==== newnewnewnew DisplayMetrics();DisplayMetrics();DisplayMetrics();DisplayMetrics(); Google Android SDK 开发范 例大全 50 getWindowManager().getDefaultDisplay().getMetrics(dm);getWindowManager().getDefaultDisplay().getMetrics(dm);getWindowManager().getDefaultDisplay().getMetrics(dm);getWindowManager().getDefaultDisplay().getMetrics(dm); StringstrOpt="手机屏幕分 辨率为: "+ dm.widthPixelsdm.widthPixelsdm.widthPixelsdm.widthPixels++++""""××××""""++++dm.heightPixels;dm.heightPixels;dm.heightPixels;dm.heightPixels; mTextView01=(TextView)findViewById(R.id.myTextView01); mTextView01.setText(strOpt); } } 扩展学习 程序一 开始所创建的 DisplayMetrics 对象 ( 程序中的 dm),不需要 传 递 任 何参 数( 构造 时 ) , 但在 调 用 getWindowManager()之后 , 会 取 得 现 有 的 Activity 的Handler ,此 时 , 调 用 getDefaultDisplay方法将 取得的宽高 维度存放于 DisplayMetrics 对象 dm中 , 而取 得的 宽 高 维 度是以 像素为单位 ( Pixel),“像素 ”所指的 是 “绝对像 素 ”而非 “相对像 素 ”。 3-6 样式化 的定型对象 —Style 样式的 定义 范例说明 老是要 一个个指定 文字的大小 、 颜 色也不是 办法, 有 没有 类似 CSS 样式的 方法可用来 指定 颜 色、 大 小呢 ?事实上是 有的,在 Android 程序开 发过程中, 也 可 以通过样式 ( Style)的方 式, 初始化 TextView 的文本 颜色、大 小;当 然这个范例 只是抛砖引 玉,在 Layout当中的 任何 对 象(以 XML 定义) 都可以用样 式化的方式 来更改其外 观。 在以下 的范例中, 将 创建两个 TextView 作为对 比, 使其 呈现两种不 同的样式差 异作为练习 , 而Style 的写法与 先前介绍到的颜色 常数( color.xml)相同, 同样是定义在 res/values下面, 但其 XML 定义的 方式不同来 看看以下这 个范例练习 。 第3章使用者 人机接口 51 运行结果 ▲图3-6 利用 Style 来初始化 TextView 范例程序 src/irdc.ex03_06/EX03_06.javasrc/irdc.ex03_06/EX03_06.javasrc/irdc.ex03_06/EX03_06.javasrc/irdc.ex03_06/EX03_06.java 主程序 看起来非常 干净, 只 有 加载 R.layout.main 定义布 局内容而已 , 但 由于定 义在 main.xml 里的语 句不同,自 然也有不同 的样貌呈现 。 packageirdc.ex03_06; importandroid.app.Activity; importandroid.os.Bundle; publicclassEX03_06extendsActivity { /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);setContentView(R.layout.main);setContentView(R.layout.main);setContentView(R.layout.main); } } res/layout/main.xmlres/layout/main.xmlres/layout/main.xmlres/layout/main.xml 诚如先前所述,初始化 TextView 时,指定 Style 属性,使其应用 style.xml 里事先定义好的 样式。 Google Android SDK 开发范 例大全 52 res/values/style.xmlres/values/style.xmlres/values/style.xmlres/values/style.xml 在此 的 style.xml 就是 这个范例的关键之处了,当中定义了两个样式名称,分别为 DavidStyleText1 与DavidStyleText2;留意于 name="DavidStyleText2">name="DavidStyleText2">name="DavidStyleText2"> 14sp #FF7F7C 0.0 0.0 第3章使用者 人机接口 53 扩展学习 style 与color的XML 语法相 类似,皆需 要先声明 xml 的版本 以及 encoding 为UTF-8,但其 内的 resources 则需要以 stylename 作为样 式名称, 在 最内层 才是以 item定义样 式的范围, 其 语法如 下: Hexvalue|stringvalue|reference+ 3-7 简易的 按钮事件 —Button 事件处 理 范例说明 按钮在 许多 Windows 窗口应 用程序中, 是最常见到 的控件( Controls),此 控件也常在 网页 设计里 出现,诸如 网页注册窗 体、应用程 序里的 “确定 ”等等。 而按钮 所触发的事 件处理, 我们称为 Event Handler, 只不过在 Android 当中, 按钮 事件是 由 系统的 Button.OnClickListener 所控制,熟悉 Java程序设计的读者对 OnXxxListener应该不 陌生。以 下的范例将示范如 何在 Activity 里布局一 个按钮( Button),并设 计这个按钮的事 件处理 函数,当点 击按钮的同 时,更改 TextView 里的文 字。 Google Android SDK 开发范 例大全 54 运行结果 ▲图3-7 Android 手机的 实际画面运行结 果 范例程序 src/irdc.ex03_07/Ex03_07.javasrc/irdc.ex03_07/Ex03_07.javasrc/irdc.ex03_07/Ex03_07.javasrc/irdc.ex03_07/Ex03_07.java 一开始 , 必 须先在 Layout当中布 局一个 Button及一个 TextView 对象, 找 不到这两 个组件 的 话,系 统会无法运 行下去,在 开发阶段会 造成编译错 误。 其次在主程序中,请留意 onCreate 里创建的 Button.OnClickListener事件,这也是触发按钮 时会运行的程序段落;但由于Eclipse 无法自动加载默认的传递参数(new Button.OnClickListener()),所以 ,在编写程序描述 时,必须自行键 入新创建的按钮所 需的 OnClickListener() 事件, 如下所示: packageirdc.ex03_07; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.Button; importandroid.widget.TextView; publicclassEX03_07extendsActivity { privateButtonmButton1; privateTextViewmTextView1; /**Calledwhentheactivityisfirstcreated.*/ 第3章使用者 人机接口 55 @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mButton1=(Button)findViewById(R.id.myButton1); mTextView1=(TextView)findViewById(R.id.myTextView1); mButton1.setOnClickListener(newmButton1.setOnClickListener(newmButton1.setOnClickListener(newmButton1.setOnClickListener(newButton.OnClickListener()Button.OnClickListener()Button.OnClickListener()Button.OnClickListener() {{{{ @Override@Override@Override@Override publicpublicpublicpublicvoidvoidvoidvoidonClick(ViewonClick(ViewonClick(ViewonClick(Viewv)v)v)v) {{{{ //TODOAuto-generatedmethodstub mTextView1.setText("Hi,mTextView1.setText("Hi,mTextView1.setText("Hi,mTextView1.setText("Hi,Everyone!!");Everyone!!");Everyone!!");Everyone!!"); }}}} });});});}); } } 扩展学习 本范例 中只有一个 按钮, 但在 Activity 里, 其 实可以 布局数个按 钮, 只 需要在 Layout里多 配 置一个 按钮对象, 以下的程序 将创建两个 按钮事件作 为示范: packageirdc.ex03_07; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.Button; importandroid.widget.TextView; publicclassEX03_07extendsActivity { privateButtonmButton1; privateButtonmButton2; privateTextViewmTextView1; /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mButton1=(Button)findViewById(R.id.myButton1); Google Android SDK 开发范 例大全 56 mButton2=(Button)findViewById(R.id.myButton2); mTextView1=(TextView)findViewById(R.id.myTextView1); mButton1.setOnClickListener(newmButton1.setOnClickListener(newmButton1.setOnClickListener(newmButton1.setOnClickListener(newButton.OnClickListener()Button.OnClickListener()Button.OnClickListener()Button.OnClickListener() { @Override publicvoidonClick(Viewv) { //TODOAuto-generatedmethodstub mTextView1.setText("Hi,Everyone!!"); } }); mButton2.setOnClickListener(newmButton2.setOnClickListener(newmButton2.setOnClickListener(newmButton2.setOnClickListener(newButton.OnClickListener()Button.OnClickListener()Button.OnClickListener()Button.OnClickListener() { @Override publicvoidonClick(Viewv) { //TODOAuto-generatedmethodstub mTextView1.setText("Hi,David!!"); } }); } } 最后来 谈谈按钮事 件里被重写的 onClick(View v) 函数, 此 函数唯 一的参数是 View类型的 变 量v, 这个变 量所指的是 来自父层 ( parent)的 ContentView, 亦即通 过 “v.*”可以更 改其 父 层的 View状态或 属性。 3-8 手机页 面的转换 —setContentView 的应用 范例说明 在网页的世界里,想要在两个网页间做转 换,只要利用超链 接( HyperLink)就可以实现, 但在手 机的世界里 ,要如何实 现手机页面 之间的转换 呢?最简单 的方式就是 改变 Activity 的 Layout!在这个范例里头,将布局两个Layout ,分别为Layout1(main.xml )与 Layout2(mylayout.xml),默认载入的 Layout为main.xml,且在 Layout1当中创建一个按 钮,当点 击按钮时,显示第 二个 Layout(mylayout.xml);同样 地,在 Layout2里也设计 一 个按钮 ,当 点击第二个 Layout的按钮 之后, 则显示回 原来的 Layout1, 现在就来示 范如何 在 两个页 面之间互相 切换。 第3章使用者 人机接口 57 运行结果 ▲图3-8 手机页面 Layout 间的切 换 范例程序 src/irdc.ex03_08/EX03_08.javasrc/irdc.ex03_08/EX03_08.javasrc/irdc.ex03_08/EX03_08.javasrc/irdc.ex03_08/EX03_08.java 主程序 中 ,预加载的 Layout是main.xml,屏幕上 显示的是黑 色背景的 “This is Layout 1!!”, 在第一个 Layout上的按钮被点击的 同时 ,改变 Activity 的Layout为mylayout.xml,屏幕上 显示变 为白色背景 的 “This is Layout 2!!”,并利用 Button点击时 ,调用方 法的不同做 两个 Layout间的切 换。 packageirdc.ex03_08; /*import相关 class*/ importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.Button; publicclassEX03_08extendsActivity { /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { Google Android SDK 开发范 例大全 58 super.onCreate(savedInstanceState); /*载入 main.xmlLayout*/ setContentView(R.layout.main);setContentView(R.layout.main);setContentView(R.layout.main);setContentView(R.layout.main); /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ Buttonb1=(Button)findViewById(R.id.button1); b1.setOnClickListener(newButton.OnClickListener() { publicvoidonClick(Viewv) { jumpToLayout2();jumpToLayout2();jumpToLayout2();jumpToLayout2(); } }); } /*methodjumpToLayout2:将 layout由main.xml切换成 mylayout.xml*/ publicpublicpublicpublicvoidvoidvoidvoidjumpToLayout2()jumpToLayout2()jumpToLayout2()jumpToLayout2() { /*将layout改成 mylayout.xml*/ setContentView(R.layout.mylayout);setContentView(R.layout.mylayout);setContentView(R.layout.mylayout);setContentView(R.layout.mylayout); /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ Buttonb2=(Button)findViewById(R.id.button2); b2.setOnClickListener(newButton.OnClickListener() { publicvoidonClick(Viewv) { jumpToLayout1();jumpToLayout1();jumpToLayout1();jumpToLayout1(); } }); } /*methodjumpToLayout1:将 layout由mylayout.xml切换成 main.xml*/ publicpublicpublicpublicvoidvoidvoidvoidjumpToLayout1()jumpToLayout1()jumpToLayout1()jumpToLayout1() { /*将layout改成 main.xml*/ setContentView(R.layout.main); /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ Buttonb1=(Button)findViewById(R.id.button1); b1.setOnClickListener(newButton.OnClickListener() { publicvoidonClick(Viewv) { jumpToLayout2();jumpToLayout2();jumpToLayout2();jumpToLayout2(); } }); } } 第3章使用者 人机接口 59 res/layout/main.xmlres/layout/main.xmlres/layout/main.xmlres/layout/main.xml 为了凸显 Layout间切换 的效果, 特 别改变 两个 Layout的背景 色及输出文 字。在 main.xml 中 定义其 背景色为黑 色,输出文 字为 “This is Layout 1!!”。 res/layout/mylayout.xmlres/layout/mylayout.xmlres/layout/mylayout.xmlres/layout/mylayout.xml 在mylayout.xml 中定义 其背景色为 白色,输出 文字为 “This is Layout 2!!”。 扩展学习 运用改变 Activity Layout这个技 巧, 就可做出手 机页面转换 的效果, 当然亦 可搭配之前 介 绍 过的 Style 与Theme 的设置 ,进行更 加灵活的布 局配置运用 ,例如, 让用户自行 决定要使 用 的系统 样式、背景 及文字颜色 等,接着直 接应用来改 变布局。 再者, 利用 setContentView 来置换 页面, 还有一 个特别的优 点, 即所有程序 里的变量皆 存 在 相同的状态,无论 是类成员变量、类函数等等,皆可 以在一个 Activity 的 状 态 中 直 接 取 得, 并没有参 数传递的问题。打 个比喻: Layout1收集了用 户输入的信用卡卡 号等付款信息, 在 “下一步 ”显示 Layout2 使之显 示订单信息 , 让 用户 进行确认, 并 在点 击按钮后, 调用 Layout3 进行刷卡 Gateway 的授权 操作, 这 当中皆没 有需要传递 的变量, 其 手法 是将所需要 的字段 数 据,以 类成员变量 作如下声明 : publicclassEX03_08extendsActivity { publicStringcolVar1; publicStringcolVar2; publicStringcolVar3; /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { /*下面的程 序略 */ 第3章使用者 人机接口 61 3-9 调用另 一个 Activity —Intent 对象的 使用 范例说明 前一个范例介绍了 如何运用切换 Layout的方式,进行手机 页面间的转换。如果要转换的页 面并不 单只是背景 、 颜 色或文字 内容的不同 , 而是 Activity 的置换 , 那 就 不是单单改变 Layout 就能完 成的,尤其 是需要传递 的变量不像 网页可以通过 Cookie 或Session,在程 序里要移交 主控权 到另外一个 Activity,光靠 先前的 Layout技巧是 办不到的。 那要如何 解 决 Activity 控制权的 移交 呢? 在 Android 的程序设 计中 ,可 在主 程序 里使 用 startActivity() 这个方 法来调用另 一个 Activity(主程 序本身即是 一个 Activity),但当 中的 关 键并不在 startActivity 这个方 法, 而是 Intent 这个特 有的对象, Intent 就如同 其英文字义 , 是 “想要 ”或“意图 ”之意, 在主 Activity 当中, 告诉程序自 己是什么, 并想要前往 哪里,这 就是 Intent 对象 所处理的事了。本范例并没有特别的Layout 布局 , 而 是 直 接 在 主 Activity(Activity1) 当 中 部署一个 按钮, 当 点击按钮 的同时, 告 诉主 Activity 前往 Activity2, 并在 Activity2里创建一 个回到 Activity1的按钮, 本范例将利用此简 易的程序描述, 示范如 何在一个 Activity 中调用 另一个 Activity 的手法 。 运行结果 ▲图3-9 在两个 Activity 间做切 换 Google Android SDK 开发范 例大全 62 范例程序 src/irdc.ex03_09/EX03_09.javasrc/irdc.ex03_09/EX03_09.javasrc/irdc.ex03_09/EX03_09.javasrc/irdc.ex03_09/EX03_09.java 主程序 中加载的 Layout为main.xml,屏幕上 显示的是黑 色背景的 “This is Activity 1!!”,在 Button被点击时调用另一个 Activity(EX03_09_1,参考 AndroidManifest.xml 里的说明 ), 并将主 Activity 关闭 finish(),接着将 主控权交给 下一个 Activity,即Activity2。 packageirdc.ex03_09; /*import相关 class*/ importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.Button; importandroid.content.Intent; publicpublicpublicpublicclassclassclassclassEX03_09EX03_09EX03_09EX03_09extendsextendsextendsextendsActivityActivityActivityActivity { /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); /*载入 main.xmlLayout*/ setContentView(R.layout.main);setContentView(R.layout.main);setContentView(R.layout.main);setContentView(R.layout.main); /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ Buttonb1=(Button)findViewById(R.id.button1); b1.setOnClickListener(newButton.OnClickListener() { publicvoidonClick(Viewv) { /*new一个 Intent对象,并 指定要启动 的 class*/ IntentIntentIntentIntentintentintentintentintent====newnewnewnewIntent();Intent();Intent();Intent(); intent.setClass(EX03_09.this,intent.setClass(EX03_09.this,intent.setClass(EX03_09.this,intent.setClass(EX03_09.this,EX03_09_1.class);EX03_09_1.class);EX03_09_1.class);EX03_09_1.class); /*调用一个新 的 Activity*/ startActivity(intent);startActivity(intent);startActivity(intent);startActivity(intent); /*关闭原本的 Activity*/ EX03_09.this.finish();EX03_09.this.finish();EX03_09.this.finish();EX03_09.this.finish(); } }); } } 第3章使用者 人机接口 63 src/irdc.ex03_09/EX03_09_1.javasrc/irdc.ex03_09/EX03_09_1.javasrc/irdc.ex03_09/EX03_09_1.javasrc/irdc.ex03_09/EX03_09_1.java EX03_09_1.java 程序是 第二个 Activity 的主程 序, 其 加载的 Layout为mylayout.xml,屏幕 上 所显示 的是白色背 景的 “This is Activity 2!!”,当主 Activity(Activity1)调用 这个 Activity (Activity2)后,同样为Button添加 onClickListener(),使Button被点击 时, 重 新调用 Activity1 (EX03_09),并将 Activity2(EX03_09_1)关闭 ( finish())。 packageirdc.ex03_09; /*import相关 class*/ importandroid.app.Activity; importandroid.os.Bundle; importandroid.content.Intent; importandroid.view.View; importandroid.widget.Button; publicpublicpublicpublicclassclassclassclassEX03_09_1EX03_09_1EX03_09_1EX03_09_1extendsextendsextendsextendsActivityActivityActivityActivity { /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); /*载入 mylayout.xmlLayout*/ setContentView(R.layout.mylayout);setContentView(R.layout.mylayout);setContentView(R.layout.mylayout);setContentView(R.layout.mylayout); /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ Buttonb2=(Button)findViewById(R.id.button2); b2.setOnClickListener(newButton.OnClickListener() { publicvoidonClick(Viewv) { /*new一个 Intent对象,并 指定要启动 的 class*/ IntentIntentIntentIntentintentintentintentintent====newnewnewnewIntent();Intent();Intent();Intent(); intent.setClass(EX03_09_1.this,intent.setClass(EX03_09_1.this,intent.setClass(EX03_09_1.this,intent.setClass(EX03_09_1.this,EX03_09.class);EX03_09.class);EX03_09.class);EX03_09.class); /*调用一个新 的 Activity*/ startActivity(intent);startActivity(intent);startActivity(intent);startActivity(intent); /*关闭原本的 Activity*/ EX03_09_1.this.finish();EX03_09_1.this.finish();EX03_09_1.this.finish();EX03_09_1.this.finish(); } }); } } Google Android SDK 开发范 例大全 64 res/layout/main.xmlres/layout/main.xmlres/layout/main.xmlres/layout/main.xml 为了凸显 Activity间 切 换的 效 果 , 特别 将 两 个 Layout的背景 及输出文字 有所区别。 在 main.xml 中定义 其背景色为 黑色,输出 文字为 “This is Activity 1!!”。 res/layout/mylayout.xmlres/layout/mylayout.xmlres/layout/mylayout.xmlres/layout/mylayout.xml 在mylayout.xml 中定义 其背景色为 白色,输出 文字为 “This is Activity 2!!”。 AndroidManifest.xmlAndroidManifest.xmlAndroidManifest.xmlAndroidManifest.xml 由于本 范例中添加 了一个 Activity, 所以 必 须 在 AndroidManifest.xml 中定义 一个新的 activity, 并给予 名称 name,否则 程序将无法 编译运行。 android:name="EX03_09_1">android:name="EX03_09_1">android:name="EX03_09_1"> 扩展学习 当系统 中新添加 Activity 时,必 须在 AndroidManifest.xml 里定义 一个新的 activity: Google Android SDK 开发范 例大全 66 否则系 统将会因为 找不到 Activity 而发生 编译错误。 另外, 当程序中出 现两个以上的 Activity 时,系 统要如何决 定主程序是 哪一支( entry point) 呢?以 本范例来说 , AndroidManifest.xml 中Activity EX03_09 的定义 如下: />/>/> />/>/> 其中有一 行为 ,这就代 表程 序启动 时, 会先运行 EX03_09 这个 Activity, 而非 EX03_09_1。 需注意 的是, 这个参数必 须 要被定 义,如果 xml 中没有 一支 Activity 有设置 这个参数, 则程序将不 会被运行。 此外,在 两支 Java 程序中的 最后一行都调用了 finish() 这个方法 ,它代表这个 Activity 已运 作完毕 , 当 系统 接收到这个 命令时, 即 会关闭此 Activity, 所以此 时 点 击模 拟 器 的 返回 ( Back) 键,并 不会回到上 一个 Activity 的画面 ,如果要让 模拟器的返 回键有回上 一页的效果 ,可以 将此行程序注释掉。同理,当两个 Activity 在切换时,并非真的只有两个 Activity 在切换, 而是在 点击按钮时 ,再重新调 用起一个新的 Activity。 3-10 不同 Activity 之间的 数据传递 —Bundle 对象的 实现 范例说明 在上一个 范例里,介绍了如 何在 Activity 中调用另 一个 Activity,但若需 要在调用另外一个 Activity 的同时传递数据, 那么就需要利用 android.os.Bundle 对象封装数据的能 力,将欲传 递的数 据或参数, 通过 Bundle 来传递 不同 Intent 之间的 数据。 本范例 的设计为一 个简易表单 的范例, 在 Activity1 中收集 User 输 入 的数 据 , 在离 开 Activity1 的同时,将 User 选择的结果传递至下一个 Activity2,以一个简单 BMI“标准体重计算器 ” 示范如 何传递数据 到下一个 Activity 里。 第3章使用者 人机接口 67 运行结果 ▲图3-10 在两个 Activity 间做数据 的传递 范例程序 src/irdc.ex03_10/EX03_10.javasrc/irdc.ex03_10/EX03_10.javasrc/irdc.ex03_10/EX03_10.javasrc/irdc.ex03_10/EX03_10.java 在第一个 Activity1 主程序 中 ,定义了“性别 ”选项的 RadioGroup以 及 输入 身 高 的 “EditText”, 并运用 Intent及Bundle对象 ,在调用 Activity2(EX03_10_1)时,同 时 将数 据 传 入 。 关 于 EditText 对象的 使用在此仅 供参考, 详 细 的应用以及 属性方法, 将 会 在未来讨论 控件时, 再 详 细解 说。 packageirdc.ex03_10; /*import相关 class*/ importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.Button; importandroid.widget.EditText; importandroid.widget.RadioButton; publicpublicpublicpublicclassclassclassclassEX03_10EX03_10EX03_10EX03_10extendsextendsextendsextendsActivityActivityActivityActivity { /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); /*载入 main.xmlLayout*/ setContentView(R.layout.main); Google Android SDK 开发范 例大全 68 /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ Buttonb1=(Button)findViewById(R.id.button1); b1.setOnClickListener(newButton.OnClickListener() { publicvoidonClick(Viewv) { /*取得输入的身高 */ EditTextet=(EditText)findViewById(R.id.height); doubleheight=Double.parseDouble(et.getText().toString()); /*取得选择的性别 */ Stringsex=""; RadioButtonrb1=(RadioButton)findViewById(R.id.sex1); if(rb1.isChecked()) { sex="M"; } else { sex="F"; } /*new一个 Intent对象,并 指定 class*/ IntentIntentIntentIntentintentintentintentintent====newnewnewnewIntent();Intent();Intent();Intent(); intent.setClass(EX03_10.this,EX03_10_1.class);intent.setClass(EX03_10.this,EX03_10_1.class);intent.setClass(EX03_10.this,EX03_10_1.class);intent.setClass(EX03_10.this,EX03_10_1.class); /*new一个 Bundle对象,并 将要传递的数 据传入 */ BundleBundleBundleBundlebundlebundlebundlebundle====newnewnewnewBundle();Bundle();Bundle();Bundle(); bundle.putDouble("height",height);bundle.putDouble("height",height);bundle.putDouble("height",height);bundle.putDouble("height",height); bundle.putString("sex",sex);bundle.putString("sex",sex);bundle.putString("sex",sex);bundle.putString("sex",sex); /*将Bundle对象 assign给Intent*/ intent.putExtras(bundle);intent.putExtras(bundle);intent.putExtras(bundle);intent.putExtras(bundle); /*调用 ActivityEX03_10_1*/ startActivity(intent);startActivity(intent);startActivity(intent);startActivity(intent); } }); } } src/irdc.ex03_10/EX03_10_1.javasrc/irdc.ex03_10/EX03_10_1.javasrc/irdc.ex03_10/EX03_10_1.javasrc/irdc.ex03_10/EX03_10_1.java 那么,在 Activity2(EX03_10_1)要 如何接收来自 Activity1(EX03_10)传递 来的数据呢 ? 试想,在 Activity1是以 Bundle 封装对象,自然在 Activity2亦是以 Bundle 的方式解开封装 的数据;程序中以 getIntent().getExtras() 方法取得随着 Bundle 对象传递过来的性 别与身高, 经过计 算之后,显 示在屏幕上 。 packageirdc.ex03_10; 第3章使用者 人机接口 69 /*import相关 class*/ importjava.text.DecimalFormat; importjava.text.NumberFormat; importandroid.app.Activity; importandroid.os.Bundle; importandroid.widget.TextView; publicclassEX03_10_1extendsActivity { /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); /*加载 main.xmlLayout*/ setContentView(R.layout.myalyout); /*取得 Intent中的 Bundle对象 */ BundleBundleBundleBundlebundebundebundebunde====this.getIntent().getExtras();this.getIntent().getExtras();this.getIntent().getExtras();this.getIntent().getExtras(); /*取得 Bundle对象中的数 据 */ Stringsex=bunde.getString("sex"); doubleheight=bunde.getDouble("height"); /*判断性别 */ StringsexText=""; if(sex.equals("M")) { sexText="男性 "; } else { sexText="女性 "; } /*取得标准体重 */ Stringweight=this.getWeight(sex,height); /*设置输出文字 */ TextViewtv1=(TextView)findViewById(R.id.text1); tv1.setText("你是一位 "+sexText+"\n你的身高是 " +height+"厘米 \n你的标准体重是 "+weight+"公斤 "); } /*四舍五入的 method*/ privateStringformat(doublenum) { NumberFormatformatter=newDecimalFormat("0.00"); Google Android SDK 开发范 例大全 70 Strings=formatter.format(num); returns; } /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ privateStringgetWeight(Stringsex,doubleheight) { Stringweight=""; if(sex.equals("M")) { weight=format((height-80)*0.7); } else { weight=format((height-70)*0.6); } returnweight; } } res/layout/mylayout.xmlres/layout/mylayout.xmlres/layout/mylayout.xmlres/layout/mylayout.xml mylayout.xml 为( EX03_10_1)的 Layout,定义 了显示计算 结果的 TextView。 AndroidManifest.xmlAndroidManifest.xmlAndroidManifest.xmlAndroidManifest.xml 由于本 范例中有两个 Activity, 所 以 文件中必须 有两个 activity的声明 , 否 则系统 将无法运 行, 请看以 下的描述。 android:name="EX03_10_1">android:name="EX03_10_1">android:name="EX03_10_1"> 扩展学习 Bundle 对象针 对了不同的 数据类型提 供了许多的 方法, 例 如 , 此 范例中传递 String 类型的 数 据,使 用的方法为 Bundle.putString(stringName,stringValue): bundle.putDouble("sex",sex); 而要传递 Double 类型的数据, 使用 的方法 为 Bundle.putDouble(doubleName,doubleValue), 如下: bundle.putString("height",height); 反之,若要由Bundle 对象中取出数据,则使用Bundle.getString(stringName) 、 Bundle.getDouble(doubleName) 等相对 应的方法即 可。 除了上 述简单的传 递类型之外 ,尚有 String[] 与ArrayList 等封装 的方式可供 使用 参考。 Google Android SDK 开发范 例大全 72 3-11 返回数 据到前一个 Activity —startActivityForResult 方法 范例说明 上一个范例中,好 不容易将数据从 Activity1 传递至 Activity2,如果要再回到 Activity1,数 据该不 会要再封装 一次吧?而 且前一个 Activity1早就被 程序 destroy 了, 倘 若在 Activity1最 后以 finish() 结束程序 ,再通过 Activity2将数据采用 Bundle 的方式通 过新打开 Activity1传 递参数 , 这 样 的做法虽然 也可以恢复 User输 入 的数 据 , 但是 并 不 符合 我 们 的 期待 , 尤其 是 User 曾经输 入过的数据 ,如果不小 心点击回到 上一页,数 据就消失不 见,这就不 妙了。 有鉴于 科技始终来 自于人性, 如果要 在次页面加 上一个 “回上页 ”的按钮 ,而非 通过模拟 器 的回复键,且回上页后又能保留之前输入的相关信息,那么就必须使用 startActivityForResult()来唤起一个 Activity。利用这 个方法,前一个 Activity1便会有一 个等 待次 Activity2的返回 ,而返回的 数据就可以 达到我们想 要的结果。 运行结果 图3-11 将数据 返回到前一个 Activity 范例程序 src/irdc.ex03_11/EX03_11.javasrc/irdc.ex03_11/EX03_11.javasrc/irdc.ex03_11/EX03_11.javasrc/irdc.ex03_11/EX03_11.java 在Activity1主程序 中调用 Activity 的方法 更改成 startActivityForResult(intent,0),其中 0为下 一个 Activity 要返回值 的依据 ,可指定为 自行定义的参考标 识符 (Identifier)。程序覆 盖了 onActivityResult() 这个方 法,令程序 在收到 result 后,再 重新加载写 回原本输入 的值。 第3章使用者 人机接口 73 packageirdc.ex03_11; /*import相关 class*/ importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.Button; importandroid.widget.EditText; importandroid.widget.RadioButton; publicclassEX03_11extendsActivity { privateEditTextet; privateRadioButtonrb1; privateRadioButtonrb2; /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); /*载入 main.xmlLayout*/ setContentView(R.layout.main); /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ Buttonb1=(Button)findViewById(R.id.button1); b1.setOnClickListener(newButton.OnClickListener() { publicvoidonClick(Viewv) { /*取得输入的身高 */ et=(EditText)findViewById(R.id.height); doubleheight=Double.parseDouble(et.getText().toString()); /*取得选择的性别 */ Stringsex=""; rb1=(RadioButton)findViewById(R.id.sex1); rb2=(RadioButton)findViewById(R.id.sex2); if(rb1.isChecked()) { sex="M"; } else { sex="F"; } /*new一个 Intent对象,并 指定 class*/ Intentintent=newIntent(); Google Android SDK 开发范 例大全 74 intent.setClass(EX03_11.this,EX03_11_1.class); /*new一个 Bundle对象,并 将要传递的数 据传入 */ Bundlebundle=newBundle(); bundle.putDouble("height",height); bundle.putString("sex",sex); /*将Bundle对象 assign给Intent*/ intent.putExtras(bundle); /*调用 ActivityEX03_11_1*/ startActivityForResult(intent,0);startActivityForResult(intent,0);startActivityForResult(intent,0);startActivityForResult(intent,0); } }); } /*覆盖 onActivityResult()*/ @Override protectedprotectedprotectedprotectedvoidvoidvoidvoidonActivityResult(intonActivityResult(intonActivityResult(intonActivityResult(intrequestCode,requestCode,requestCode,requestCode,intintintintresultCode,resultCode,resultCode,resultCode, IntentIntentIntentIntentdata)data)data)data) { switch(resultCode) { caseRESULT_OK: /*取得来自 Activity2的数据,并显示 于画面 上 */ BundleBundleBundleBundlebundebundebundebunde====data.getExtras();data.getExtras();data.getExtras();data.getExtras(); StringStringStringStringsexsexsexsex====bunde.getString("sex");bunde.getString("sex");bunde.getString("sex");bunde.getString("sex"); doubledoubledoubledoubleheightheightheightheight====bunde.getDouble("height");bunde.getDouble("height");bunde.getDouble("height");bunde.getDouble("height"); et.setText(""+height); if(sex.equals("M")) { rb1.setChecked(true); } else { rb2.setChecked(true); } break; default: break; } } } src/irdc.ex03_11/EX03_11_1.javasrc/irdc.ex03_11/EX03_11_1.javasrc/irdc.ex03_11/EX03_11_1.javasrc/irdc.ex03_11/EX03_11_1.java 在Activity2 的主程序中 ,设 计 当 Button被点击时, 将 Bundle 对象与结果 返回 给前 一 个 Activity1。 第3章使用者 人机接口 75 packageirdc.ex03_11; /*import相关 class*/ importjava.text.DecimalFormat; importjava.text.NumberFormat; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.Button; importandroid.widget.TextView; publicclassEX03_11_1extendsActivity { Bundlebunde; Intentintent; /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); /*载入 mylayout.xmlLayout*/ setContentView(R.layout.myalyout); /*取得 Intent中的 Bundle对象 */ intent=this.getIntent(); bunde=intent.getExtras(); /*取得 Bundle对象中的数 据 */ Stringsex=bunde.getString("sex"); doubleheight=bunde.getDouble("height"); /*判断性别 */ StringsexText=""; if(sex.equals("M")) { sexText="男性 "; } else { sexText="女性 "; } /*取得标准体重 */ Stringweight=this.getWeight(sex,height); /*设置输出文字 */ TextViewtv1=(TextView)findViewById(R.id.text1); tv1.setText("你是一位 "+sexText+"\n你的身高是 "+height+ Google Android SDK 开发范 例大全 76 "厘米 \n你的标准体重是 "+weight+"公斤 "); /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ Buttonb1=(Button)findViewById(R.id.button1); b1.setOnClickListener(newButton.OnClickListener() { publicvoidonClick(Viewv) { /*返回 result回上一个 activity*/ EX03_11_1.this.setResult(RESULT_OK,EX03_11_1.this.setResult(RESULT_OK,EX03_11_1.this.setResult(RESULT_OK,EX03_11_1.this.setResult(RESULT_OK,intent);intent);intent);intent); /*结束这 个 activity*/ EX03_11_1.this.finish();EX03_11_1.this.finish();EX03_11_1.this.finish();EX03_11_1.this.finish(); } }); } /*四舍五入的 method*/ privateStringformat(doublenum) { NumberFormatformatter=newDecimalFormat("0.00"); Strings=formatter.format(num); returns; } /*以findViewById()取得 Button对象,并 添 加 onClickListener*/ privateStringgetWeight(Stringsex,doubleheight) { Stringweight=""; if(sex.equals("M")) { weight=format((height-80)*0.7); } else { weight=format((height-70)*0.6); } returnweight; } } res/layout/mylayout.xmlres/layout/mylayout.xmlres/layout/mylayout.xmlres/layout/mylayout.xml mylayout.xml 为Activity2(EX03_11_1)的 Layout,其中定义了显示计算结果 的 TextView 与回上 一页的 Button按钮。 AndroidManifest.xmlAndroidManifest.xmlAndroidManifest.xmlAndroidManifest.xml 范例中有两个 Activity,所以 AndroidManifest.xml 里必须有这两个 activity 的声明,否则系 统将无 法运行。 android:name="EX03_11_1">android:name="EX03_11_1">android:name="EX03_11_1"> Google Android SDK 开发范 例大全 78 扩展学习 范例中 为了在回到 上一页时, 能 够 显示之前 所输入的数 据, 故 将原本 传递次 Activity 的Intent (里面 包含了有数 据的 Bundle 对象) 再重新返回 给主 Activity1。如果 要在次 Activity2中返 回其它的数据,例如,经过计算后的结果、数据,此时只需将要返回的数据再放入 Bundle 对象中 即可达成。 此 外 , 以本 范例 而 言 , 其实 使 用 startActivity()也可达 成同样的结 果, 仅 需 在主 Activity 被create 时去判断 Intent 内有没有数据,有的话,就将数据带入;没有的话,就带入空值( null)。 但程序 还需要再做 有无值的比 较,较为繁 琐,既然 Android API 中有提 供更好用的 方法,何 来不用 的道理?更 何况如果系 统不是只有 几行代码, 而是 几十行、 几百行 代码, 那时头可 就 大了! (本章 未完结)
还剩43页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 1 人已下载

下载pdf

pdf贡献者

ztj_5451

贡献于2011-06-29

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf