Google Android SDK开发范例大全
第3章 使用者人机接口
用户人机界面
3-1
更改与显示文字标签
— TextView标签的使用
范例说明
前一章写了Hello World之后,一直觉得没有写半行代码对不起自己,所以在本章人机界面一开始,则延续Hello Wolrd的气势,进行与TextView文字标签的第一次接触。在此范例中,将会在Layout中创建TextView对象,并学会定义res/values/strings.xml里的字符串常数,最后通过TextView的setText
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
,在预加载程序之初,更改TextView文字。
运行结果
▲图3-1 认识TextView.setText更改默认Layout里定义的文本字符串
范例程序
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
{
/*必须引用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对象 */
mTextView01 = (TextView) findViewById(R.id.myTextView01);
String str_2 = "欢迎来到Android的TextView世界...";
mTextView01.setText(str_2);
}
}
res/layout/main.xml
以android:id命名TextView的ID为mTextView01;在较旧的版本写法与1.0的不同,请特别留意。
扩展学习
TextView里的setText方法支持以下多态构造方法:
public final void setText(CharSequence text)
public final void setText(int resid)
public void setText(CharSequence text, 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];
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不支持HTML TAG的输出,所以即便写成这样:
mTextView01.setText("
戴维的博客");
实际输出时,也就是纯文本而已,并不会作HTML TAG的转换。但若撇开HTML TAG之外(如“<”开头的标记),在TextView里加上了android:autoLink="all",那么正文中若有网址(http://),是可以被显示的,以下这个范例就交给你自己实现看看。
3-2
更改手机窗口画面底色
— drawable定义颜色常数的方法
范例说明
在之前的范例运行结果,窗口的底色一律是“深黑色”,这是SDK默认的颜色,要更改Activity里的窗口底色有许多方法,最简单的方法就是将颜色色码事先定义在drawable当中,当程序onCreate创建的同时,加载预先定义的画面颜色。
此范例程序的设计方式是在drawable里指定Layout的背景色(BackGround)为白色,但这里的“白色”(颜色色码为#FFFFFFFF)预先定义在drawable当中,当程序运行时,背景就会变为白色。
这是指定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 android.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/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);
TextView tv = (TextView)findViewByID(R.id.text);
tv.setBackground(HippoDrawable);
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.java
程序里新建两个类成员变量:mTextView01与mTextView02,这两个变量在onCreate之初,以findViewById方法使之初始化为layout(main.xml)里的TextView对象。在当中使用了Resource类以及Drawable类,分别创建了resources对象以及HippoDrawable对象,并将前一个范例中所创建的R.drawable.white以getDrawable方法加载,最后则调用了setBackgroundDrawable来更改mTextView01的文字底纹。更改TextView里的文字,则使用了setText方法。
在mTextView02当中,使用了graphics.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 extends 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);
mTextView01 = (TextView) findViewById(R.id.myTextView01);
mTextView01.setText("我是应用Drawable背景色的戴维文本。");
Resources resources = getBaseContext().getResources();
Drawable HippoDrawable = resources.getDrawable(R.drawable.white);
mTextView01.setBackgroundDrawable(HippoDrawable);
mTextView02 = (TextView) findViewById(R.id.myTextView02);
/*下使用Color.MAGENTA指定文本的颜色为紫红色*/
mTextView02.setTextColor(Color.MAGENTA);
}
}
扩展学习
Resources resources = getBaseContext().getResources();
Drawable HippoDrawable = resources.getDrawable(R.drawable.white);
上述这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.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
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.CharSequence这个Interface来取得存放在global里的Resource ID
范例程序
src/irdc.ex03_04/EX03_04.java
主程序的差异主要是在更改mTextView02的文字时(setText方法),合并了str_3与str_2这两个不同对象,由于setText方法同时支持CharSequence与String类型的参数,故在此示范不同数据类型的字符串进行同步输出。
package irdc.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 savedInstanceState)
{
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);
}
}
res/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-5 取得Android手机的实际屏幕分辨率
范例程序
src/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 */
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
String strOpt = "手机屏幕分辨率为:" +
dm.widthPixels + " × " + 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-6 利用Style来初始化TextView
范例程序
src/irdc.ex03_06/EX03_06.java
主程序看起来非常干净,只有加载R.layout.main定义布局内容而已,但由于定义在main.xml里的语句不同,自然也有不同的样貌呈现。
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(savedInstanceState);
setContentView(R.layout.main);
}
}
res/layout/main.xml
诚如先前所述,初始化TextView时,指定Style属性,使其应用style.xml里事先定义好的样式。
res/values/style.xml
在此的style.xml就是这个范例的关键之处了,当中定义了两个样式名称,分别为DavidStyleText1与DavidStyleText2;留意于
扩展学习
style与color的XML语法相类似,皆需要先声明xml的版本以及encoding为UTF-8,但其内的resources则需要以stylename作为样式名称,在最内层才是以item定义样式的范围,其语法如下:
3-7
简易的按钮事件
— Button事件处理
范例说明
按钮在许多Windows窗口应用程序中,是最常见到的控件(Controls),此控件也常在网页设计里出现,诸如网页注册窗体、应用程序里的“确定”等等。
而按钮所触发的事件处理,我们称为Event Handler,只不过在Android当中,按钮事件是由系统的Button.OnClickListener所控制,熟悉Java程序设计的读者对OnXxxListener应该不陌生。以下的范例将示范如何在Activity里布局一个按钮(Button),并设计这个按钮的事件处理函数,当点击按钮的同时,更改TextView里的文字。
运行结果
▲图3-7 Android手机的实际画面运行结果
范例程序
src/irdc.ex03_07/Ex03_07.java
一开始,必须先在Layout当中布局一个Button及一个TextView对象,找不到这两个组件的话,系统会无法运行下去,在开发阶段会造成编译错误。
其次在主程序中,请留意onCreate里创建的Button.OnClickListener事件,这也是触发按钮时会运行的程序段落;但由于Eclipse无法自动加载默认的传递参数(new Button.OnClickListener()),所以,在编写程序描述时,必须自行键入新创建的按钮所需的OnClickListener() 事件,如下所示:
package irdc.ex03_07;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class EX03_07 extends Activity
{
private Button mButton1;
private TextView mTextView1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButton1 =(Button) findViewById(R.id.myButton1);
mTextView1 = (TextView) findViewById(R.id.myTextView1);
mButton1.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
mTextView1.setText("Hi, Everyone!!");
}
});
}
}
扩展学习
本范例中只有一个按钮,但在Activity里,其实可以布局数个按钮,只需要在Layout里多配置一个按钮对象,以下的程序将创建两个按钮事件作为示范:
package irdc.ex03_07;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class EX03_07 extends Activity
{
private Button mButton1;
private Button mButton2;
private TextView mTextView1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButton1 =(Button) findViewById(R.id.myButton1);
mButton2 =(Button) findViewById(R.id.myButton2);
mTextView1 = (TextView) findViewById(R.id.myTextView1);
mButton1.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
mTextView1.setText("Hi, Everyone!!");
}
});
mButton2.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
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-8 手机页面Layout间的切换
范例程序
src/irdc.ex03_08/EX03_08.java
主程序中,预加载的Layout是main.xml,屏幕上显示的是黑色背景的“This is Layout 1!!”,在第一个Layout上的按钮被点击的同时,改变Activity的Layout为mylayout.xml,屏幕上显示变为白色背景的“This is Layout 2!!”,并利用Button点击时,调用方法的不同做两个Layout间的切换。
package irdc.ex03_08;
/* import相关class */
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class EX03_08 extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 载入main.xml Layout */
setContentView(R.layout.main);
/* 以findViewById()取得Button对象,并添加onClickListener */
Button b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
jumpToLayout2();
}
});
}
/* method jumpToLayout2:将layout由main.xml切换成mylayout.xml */
public void jumpToLayout2()
{
/* 将layout改成mylayout.xml */
setContentView(R.layout.mylayout);
/* 以findViewById()取得Button对象,并添加onClickListener */
Button b2 = (Button) findViewById(R.id.button2);
b2.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
jumpToLayout1();
}
});
}
/* method jumpToLayout1:将layout由mylayout.xml切换成main.xml */
public void jumpToLayout1()
{
/* 将layout改成main.xml */
setContentView(R.layout.main);
/* 以findViewById()取得Button对象,并添加onClickListener */
Button b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
jumpToLayout2();
}
});
}
}
res/layout/main.xml
为了凸显Layout间切换的效果,特别改变两个Layout的背景色及输出文字。在main.xml中定义其背景色为黑色,输出文字为“This is Layout 1!!”。
re