1、第3章 使用者人机接口 用户人机界面 3-1 更改与显示文字标签 — TextView标签的使用 范例说明 前一章写了Hello World之后,一直觉得没有写半行代码对不起自己,所以在本章人机界面一开始,则延续Hello Wolrd的气势,进行与TextView文字标签的第一次接触。在此范例中,将会在Layout中创建TextView对象,并学会定义res/values/strings.xml里的字符串常数,最后通过TextView的setText方法,在预加载程序之初,更改TextView文字。 运行结果 ▲图3-1 认识TextView.setText更改默认L
2、ayout里定义的文本字符串 范例程序 src/irdc.ex03_01/EX03_01.java 主程序示范以setText方法,输出String类型的字符串变量。 package irdc.ex03_01; import android.app.Activity; import android.os.Bundle; /*必须引用widget.TextView才能在程序里声明TextView对象*/ import android.widget.TextView; public class EX03_01 extends Activity { /*必须引
3、用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 */
4、 setContentView(R.layout.main); /* 使用findViewBtId函数,利用ID找到该TextView对象 */ mTextView01 = (TextView) findViewById(R.id.myTextView01); String str_2 = "欢迎来到Android的TextView世界..."; mTextView01.setText(str_2); } } res/layout/main.xml 以android:id命名TextView的ID为mTextVie
5、w01;在较旧的版本写法与1.0的不同,请特别留意。
6、height="wrap_content"
android:text="@string/str_1"
android:layout_x="61px"
android:layout_y="69px"
>
7、 TextView.BufferType type) public final void setText(int resid, TextView.BufferType type) public final void setText(char[] text, int start, int len) 在此,以最后setText(char[] text, int start, int len) 为例,第一个参数为char数组作为输出依 据,第二个参数为从哪一个元素索引开始选取,第三个参数则为要取出多少个元素,请看以下的例子: char char_1[] = new char[5]; ch
8、ar_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不支持HTML TAG的输出,所以即便写成这样: mTextView01.setText("戴维的博客"); 实际输出时
9、也就是纯文本而已,并不会作HTML TAG的转换。但若撇开HTML TAG之外(如“<”开头的标记),在TextView里加上了android:autoLink="all",那么正文中若有网址(http://),是可以被显示的,以下这个范例就交给你自己实现看看。
11、 这是指定Activity Layout背景颜色最简单的方法,在范例最末,则将示范如何创建色彩板(color table),让Android手机程序可以像使用“常数”般直接取用,并反应在应用程序的运行阶段。 运行结果 ▲图3-2 使用drawable设置颜色常数,应用于程序运行时的结果 范例程序 src/irdc.ex03_02/EX03_02.java 程序继承自Activity类,并在重写 onCreate创建之初,直接显示R.layout.main(main.xml)这个页面安排的布局配置。 package irdc.ex03_02; import andr
12、oid.app.Activity; import android.os.Bundle; public class EX03_02 extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } } res
13、/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里看见颜色的定义描述。
14、"1.0" encoding="utf-8"?>
15、"wrap_content"
android:text="@string/str_id"
android:textColor="@drawable/darkgray"
android:layout_x="61px"
android:layout_y="69px"
>
16、ndroid:textColor="@drawable/darkgray"
android:layout_x="61px"
android:layout_y="158px"
>
17、ext>
18、放于resources当中,这是开发Android程序的好习惯,正如同字符串常数一样,颜色也是可以事先定义好的。在本范例中学会了使用drawable的resource的定义方法:
19、rawable HippoDrawable = resources.getDrawable(R.drawable.white); TextView tv = (TextView)findViewByID(R.id.text); tv.setBackground(HippoDrawable); 3-3 更改TextView文字颜色 — 引用Drawable颜色常数及背景色 范例说明 上一个范例通过Drawable来定义颜色常数,但实际设计中最常用的方法,则是使用程序控制TextView或其它对象的背景色(setBackgroundDrawable方法),如判断对象被点击时的背景
20、色亮起、当失去焦点时,又恢复成原来的背景色等等。 以下的范例,将扩展前一个范例的实现,预先在Layout当中设计好两个TextView,并在onCreate同时,通过两种程序描述方法,实时更改原来Layout里TextView的背景色以及文字颜色,最后学会使用Android默认的颜色常数(graphics.Color)来更改文字的前景色。 运行结果 ▲图3-3 通过setBackgroundDrawable方法更改TextView的背景色以及graphics.Color更改前景色 范例程序 src/irdc.ex03_03/EX03_03.java 程序里新建两个类成员
21、变量:mTextView01与mTextView02,这两个变量在onCreate之初,以findViewById方法使之初始化为layout(main.xml)里的TextView对象。在当中使用了Resource类以及Drawable类,分别创建了resources对象以及HippoDrawable对象,并将前一个范例中所创建的R.drawable.white以getDrawable方法加载,最后则调用了setBackgroundDrawable来更改mTextView01的文字底纹。更改TextView里的文字,则使用了setText方法。 在mTextView02当中,使用了grap
22、hics.Color里的颜色常数,接着,再利用setTextColor更改文字的前景色。 package irdc.ex03_03; import android.app.Activity; import android.content.res.Resources; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.widget.TextView; public class EX03_03 e
23、xtends Activity { private TextView mTextView01; private TextView mTextView02; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); m
24、TextView01 = (TextView) findViewById(R.id.myTextView01); mTextView01.setText("我是应用Drawable背景色的戴维文本。"); Resources resources = getBaseContext().getResources(); Drawable HippoDrawable = resources.getDrawable(R.drawable.white); mTextView01.setBackgroundDrawable(HippoDrawable);
25、 mTextView02 = (TextView) findViewById(R.id.myTextView02); /*下使用Color.MAGENTA指定文本的颜色为紫红色*/ mTextView02.setTextColor(Color.MAGENTA); } } 扩展学习 Resources resources = getBaseContext().getResources(); Drawable HippoDrawable = resources.getDrawable(R.drawable.white); 上述这
26、2行代码,在前一版本中的写法是这样的: Resources.resources = getDrawable(R.drawable.solid_red); Drawable HippoDrawable = resources.getDrawable(R.drawable.white); 但是在1.0之后的版本,Resources不再支持直接使用 .getDrawable方法直接取用drawable,而必须先取得基类的Context才行。 此外,在程序里使用了Color.MAGENTA让TextView里的文字变成了粉红色,事实上,在Android里还有以下12种常见的颜色: Color
27、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
28、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 0xfff
29、fff00 3-4 置换TextView文字 — CharSequence数据类型与Resource ID应用 范例说明 从一开始自Layout里通过Resource初始化TextView的文字,到程序中动态更改TextView文字,但要如何在代码里取得Resource的字符串呢?在Android里,确实是有些方法可以直接以R.string.*直接转换ID为String,不过,这样的数据类型转换是非常规甚至是不妥的,正确的方法是利用Context.getString方法来取得存放在global里的Resource ID。以下这个范例将示范如何在程序运行时(runtime),通过C
30、harSequence依据Resource ID取出字符串,并正确更改TextView的文字。 运行结果 ▲图3-4 通过java.lang.CharSequence这个Interface来取得存放在global里的Resource ID 范例程序 src/irdc.ex03_04/EX03_04.java 主程序的差异主要是在更改mTextView02的文字时(setText方法),合并了str_3与str_2这两个不同对象,由于setText方法同时支持CharSequence与String类型的参数,故在此示范不同数据类型的字符串进行同步输出。 package i
31、rdc.ex03_04; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class EX03_04 extends Activity { private TextView mTextView02; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceStat
32、e) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTextView02 = (TextView) findViewById(R.id.myTextView02); CharSequence str_2 = getString(R.string.str_2); String str_3 = "我是程序里调用Resource的"; mTextView02.setText(str_3 + str_2);
33、 }
}
res/layout/main.xml
为了作为对比,在main.xml里创建了两个TextView,并采LinearLayout的方式配置,一上一下,在运行结果中id为myTextView01的TextView并没有任何文字的更改,维持一开始的str_1(参考字符串常数里的文字),但在程序运行后,id为myTextView02的TextView则作了文字的实时更改。
34、 android:background="@drawable/white"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
36、> 扩展学习 虽然在values/strings.xml里定义了默认的字符串常数,需留意若遭遇如“?”、“'”、“\”等符号时,必须使用转义字符(\),如下: \? \' \\ 3-5 取得手机屏幕大小 — DisplayMetrics取得画面宽高的方法 范例说明 在开发手机应用程序时,除了底层对API的掌握度之外,最重要的仍是对屏幕分辨率的概念,因各家手机厂商所采用的屏幕尺寸不同,user UI接口呈现及布局自然也各异。 尽管Android可设置为随着窗口大小调整缩放比例,但即便如此,手机程序设计人员还是必须知道手机屏幕的边界,以避免缩放造成的布局(Layout)
37、变形问题。这个范例非常的简短,只需几行程序即可取得手机的分辨率,当中的关键则是DisplayMetrics类的应用。 运行结果 ▲图3-5 取得Android手机的实际屏幕分辨率 范例程序 src/irdc.ex03_05/EX03_05.java 在android.util底下的DisplayMetrics对象,记录了一些常用的信息,包含了显示信息、大小、维度、字体等等;在使用时,请记得引用android.util.DisplayMetrics。值得一提的是DisplayMetrics对象里的widthPixels及heightPixels字段为整数类型,在以下的程序当
38、中,并没有对其作字符串类型的转换,因为字符串连接运算符的缘故,所以输出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 t
39、he activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /* 必须引用 android.util.DisplayMetrics */ DisplayMetrics dm = new DisplayMetrics(); getWindowManager().
40、getDefaultDisplay().getMetrics(dm); String strOpt = "手机屏幕分辨率为:" + dm.widthPixels + " × " + dm.heightPixels; mTextView01 = (TextView) findViewById(R.id.myTextView01); mTextView01.setText(strOpt); } } 扩展学习 程序一开始所创建的DisplayMetrics对象(程序中的dm),不需要传递任何参数(构造时
41、但在调用getWindowManager()之后,会取得现有的Activity的Handler,此时,调用getDefaultDisplay方法将取得的宽高维度存放于DisplayMetrics对象dm中,而取得的宽高维度是以像素为单位(Pixel),“像素”所指的是“绝对像素”而非“相对像素”。 3-6 样式化的定型对象 — Style样式的定义 范例说明 老是要一个个指定文字的大小、颜色也不是办法,有没有类似CSS样式的方法可用来指定颜色、大小呢?事实上是有的,在Android程序开发过程中,也可以通过样式(Style)的方式,初始化TextView的文本颜色、大小;当然这个
42、范例只是抛砖引玉,在Layout当中的任何对象(以XML定义)都可以用样式化的方式来更改其外观。 在以下的范例中,将创建两个TextView作为对比,使其呈现两种不同的样式差异作为练习,而Style的写法与先前介绍到的颜色常数(color.xml)相同,同样是定义在res/values下面,但其XML定义的方式不同来看看以下这个范例练习。 运行结果 ▲图3-6 利用Style来初始化TextView 范例程序 src/irdc.ex03_06/EX03_06.java 主程序看起来非常干净,只有加载R.layout.main定义布局内容而已,但由于定义在main.xml里
43、的语句不同,自然也有不同的样貌呈现。 package irdc.ex03_06; import android.app.Activity; import android.os.Bundle; public class EX03_06 extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstance
44、State);
setContentView(R.layout.main);
}
}
res/layout/main.xml
诚如先前所述,初始化TextView时,指定Style属性,使其应用style.xml里事先定义好的样式。
45、"fill_parent"
android:layout_height="fill_parent"
>
47、tyle.xml 在此的style.xml就是这个范例的关键之处了,当中定义了两个样式名称,分别为DavidStyleText1与DavidStyleText2;留意于 扩展学习 style与col
49、or的XML语法相类似,皆需要先声明xml的版本以及encoding为UTF-8,但其内的resources则需要以stylename作为样式名称,在最内层才是以item定义样式的范围,其语法如下: 3-7 简易的按钮事件 — Button事件处理 范例说明 按钮在许多Windows窗口应用程序中,是最常见到的控件(Controls),此控件也常在网页设计里出现,诸如网页注册窗体、应用程序里的“确定”等等。 而按钮所触发的事件处理,我们称为Event Handler,只不过在Android当中,按钮事件是由系统的Butt






