作者:Confach 发表于April 23,2006 15:02 pm
版权信息:可以任意转载, 转载时请务必以超链接形式标明文章原始出处 和作者信息.
http://www.cnblogs.com/confach/articles/382744.html
第3章 创建用户接口(UI)
|
UI API
显示UI组件。
管理UI组件
创建客户定制的UI组件
操作图片
使用图像对象画图
监听UI对象的改变
|
UI API
当你为BlackBerry设备编写应用程序时,使用下面2组UI API的一组:
- <!--[if !supportLists]--> <!--[endif]-->MIDP UI API (javax.microedition.lcdui包)
- BlackBerry UI API (net.rim.device.api.ui包)
如果你正在编写一个在任何MIDP兼容设备上运行的应用程序,请使用MIDP UI API.如果你正在编写专门运行在BlackBerry设备上的应用程序,那就使用BlackBerry UI API吧。BlackBerry API提供了访问BlackBerry设备的特定特性的功能,并且也允许更成熟的UI布局(layout)和交互。
<!--[if !vml]--><!--[endif]-->
注:不要在同一个程序里既使用MIDP UI API,又使用BlackBerry UI API,否则会抛出异常。在应用程序中,UI框架支持一中类型的UI对象。
显示UI组件
显示屏幕(Screen)
UI 的主要结构是Screen。一个应用程序一次只能显示一个屏幕。
<!--[if !vml]-->
注:不要使用Screen对象来输入文本。Screen对象没有明确实现此功能,它需要复杂的输入方法,例如国际化的键盘和7100系列的设备。为实现无缝得集成不同输入方法,扩展Field或者其任一子类。参看53页“创建定制的域”得到更多信息。
显示栈(Stack)
Screen对象在一个一组有序的Screen显示栈里得到维护。在栈顶的Screen对象是显示给用户的活动Screen。当应用程序显示一个Screen时,它将这个Screen压入到栈顶。当关闭一个Screen,将这个Screen从栈里移出,然后显示栈里的下一个Screen,如果必要会重绘它。
注:每个Screen在栈里只出现一次。如果同一个Screen压入到栈不止一次,VM会抛出一个运行时异常。当用户完成和Screen交互,应用程序必须将Screen从栈里移出,以致内存不必再用。不要在同一时间里使用多个Screen,因为每个Screen使用独立的线程。
Screen的类型
在多数情况下,创建一个Screen最有效的方法是创建一个扩展Screen或其任一子类,FullScreen或MainScreen的类。
|
类
|
描述
|
|
Screen
|
使用Screen类定义一个管理器布局Screen上的UI组件,并且使用在超类Field定义的常数的样式(Style)定义一明确的Screen。
|
|
FullScreen
|
缺省的,一个FullScreen包含单个垂直<!--[if !supportFootnotes]-->[1]<!--[endif]-->的域管理器(Field Manager)。使用一个FullScreen提供了一个空的Screen,在这个空的Screen上,你可以增加UI组件到这个标准的垂直布局里。如果需要另外类型的布局,例如水平的或对角的,使用一个Screen类,并且在里面增加一个管理器。
|
|
MainScreen
|
MainScreen类提供常见的标准BlackBerry应用程序常见特性。对你的应用程序的第一个Screen,使用一个MainScreen对象来保持和其他BlackBerry应用程序的统一。MainScreen提供一下的UI组件:
<!--[if !supportLists]-->l <!--[endif]-->Screen标题的缺省位置,标题后的一个SeperatorField
<!--[if !supportLists]-->l <!--[endif]-->一个包含在VerticalManager里的滚动的主界面。
<!--[if !supportLists]-->l <!--[endif]-->有一个Close菜单项的菜单。
<!--[if !supportLists]-->l <!--[endif]-->当用户点击Close菜单项或者按Escape键时缺省的关闭操作。
|
响应用户交互
BlackBerry API提供一个和Java标准版本类似的事件监听框架。特殊的,2个监听接口使程序接收和响应用户交互:TrackWheelListener和KeyboardListnener。Screen类和其子类都实现了这些方法。
提供screen导航(navigation)
BlackBerry应用程序为用户提供一个菜单来完成操作。避免使用按钮(Button)或其他占据Screen空间的UI组件。
注:按滑轮访问菜单。
当创建一个FullScreen或Screen,在构造子里指明DEFAULT_MENU和DEFAULT_CLOSE参数来提供缺省的导航。
FullScreen fullScreen = new FullScreen(DEFAULT_MENU | DEFAULT_CLOSE);
|
参数
|
描述
|
|
DEFAULT_MENU
|
这个参数增加一个缺省的菜单,它包含了不同的菜单项,这依赖域用户的上下文环境。例如,如果一个EditField获得焦点,将显示Cut,Copy和Paste菜单项。所有已选择的域提供Select和Cancel Selection菜单项。
|
|
DEFAULT_CLOSE
|
这个参数增加一个缺省行为的Close菜单项到菜单,当用户点击Close菜单项或者按Escapes按钮,如果Screen上的任何东西改变,一个确认的对话框将会出现。如果这个Screen是栈里的唯一一个Screen,应用程序将关闭。
|
当创建一个MainScreen时,缺省的导航会自动提供。
增加菜单项
创建MenuItem对象。
|
private MenuItem viewItem = new MenuItem("View Message", 100, 10) {
public void run() {
Dialog.inform("This is today’s message");
}
};
|
MenuItem构造子接受下面的3个参数:
|
参数
|
描述
|
|
text
|
菜单项的名称
|
|
ordinal
|
菜单项的顺序;一个越大的值表明了这个菜单项越靠近菜单的底部。
|
|
priority
|
接收缺省焦点的菜单项优先级
|
run()定义了当用户点击菜单项发生的操作的实现。如果你没有使用本地资源,重写toString()方法来指定菜单项的名字。
为了在应用程序加入上下文菜单给field,调用getLeafFieldWithFocus(),并且调用getContextMenu(),其返回值决定哪一个Field接收makeMenu()里的客户化菜单项。为了得到更多信息,参看60页的“创建客户化的上下文菜单”。
当增加你自己的菜单项时,显式的定义一个Close菜单项。
为了增加菜单项到Screen里,重写Screen.makeMenu()方法:
|
protected void makeMenu(Menu menu, int instance) {
menu.add(viewItem);
menu.add(closeItem);
}
|
如果你扩展Screen或其任一子类,那么当用户点击滑轮时,缺省的TrackwheelListener实现调用makeMenu()。
如果你没有扩展Screen,那么实现TrackwheelListener。特殊地,trackwheelClick()的实现创建一个新的菜单,增加菜单项以及在Screen上显示菜单。
|
public boolean trackwheelClick(int status, int time) {
Menu appMenu = new Menu();
makeMenu(appMenu, 0); // Add menu items.
appMenu.show(); // Display the menu on screen.
return true;
}
|
注:为了创建菜单项提供附加的功能,请扩展MenuItem类。为了得到更多信息,参看60页“创建客户化的上下文菜单”。
显示对话框
PopupScreen类通过使用它的子类,Dialog和Status,来提供创建对话框和状态Screen的特性。Popup screen不会压入到显示栈中,为了显示一个popup screen,调用Dialog.ask(int)或Status.show().
为了控制对话框的布局,使用DialogFieldManager对象,为了得到更多的信息,参看50页的“为一个PopupScreeen指定布局”。
为了显示一个对话框,使用下面的一个参数来调用Dialog.ask():
|
参数
|
描述
|
|
D_OK
|
显示一个字符串,并且提示用户点击OK。
|
|
D_SAVE
|
实现一个字符串,并且提示用户点击Save,Discard,或者Cancel;按Escape取消。
|
|
D_DELETE
|
显示一个字符串,并且提示用户点击Delete或者Cancel;按Escape撤销。
|
|
D_YES_NO
|
显示一个字符串,并且提示用户点击Yes或No。
|
|
int response = Dialog.ask(Dialog.D_SAVE);
if (Dialog.SAVE == response || Dialog.CANCEL == response)
return false;
if ( Dialog.DISCARD == response )
_item.deleteItem(_itemIndex);
|
为了指定一个对话框的缺省的响应,使用一个接受defaultChoice作为参数的Dialog.ask()版本。
|
int response = Dialog.ask(Dialog.D_YES_NO, "Are you sure?", Dialog.NO);
|
显示状态消息
调用Status.Show()显示一个状态消息。缺省的,状态屏幕保留其屏幕 2秒钟。
Status.show("Status screen message");
参看API参考获取Status.Show()的版本信息,它使你可以指定额外的参数,例如不同的图标或者保持状态对话框可见的时间长短。你可以创建模态的状态对话框(需要用户取消它们),也可以创建计时的状态对话框(在指定的时间后自动取消)。
显示域(Field)
所有UI组件以包含在管理器里的成矩形的field的形式表现。Field的大小取决于它的布局需求。管理器为它们包含的field提供滚动(条)。
BlackBerry JDE在net.rim.device.api.ui.component包里提供一个预创建接口控件和组件的库。多数情况下,你可以使用这些对象构建UI应用程序。
为了创建指定的field控件(如包含多个元素的文本field),扩展Field类或者其任意子类来创建你自己定制的类型。为得到更多信息,参看53页的“创建定制的field”。
注:参看API参考获取更多关于指定field类的有效、支持的格式的信息。如果使用一个不支持的格式实例化一个Field,将抛出一个IllegalArgumentException异常。
Bitmap Field
一个BitmapField包含了位图。当使用Graphics对象绘图时使用BitmapField。为了修改一个field的内容,调用BitmapField的绘图方法。为得到更多信息,参看73页的“使用graphics对象绘图”.
|
Bitmap myBitmap = Bitmap.getPredefinedBitmap(Bitmap.INFORMATION);
BitmapField myBitmapField = new BitmapField(myBitmap.getPredefinedBitmap(myBitmap));
...
mainScreen.add(myBitmapField);
|
有4种预定义的位图:
- <!--[if !supportLists]-->Bitmap.INFORMATION
- <!--[if !supportLists]--><!--[endif]-->Bitmap.QUESTION
- <!--[if !supportLists]-->Bitmap.EXCLAMATION
- <!--[if !supportLists]-->Bitmap.HOURGLASS
为了使用原始的.gif或.png作为位图,调用getBitmapResource().
注:一个二进制资源的大小,如一个.png文件,不能超过63,000字节。
|
private static final Bitmap myBitmap =
Bitmap.getBitmapResource("customBitmap.gif");
...
BitmapField bitmapField = new BitmapField(myBitmap);
mainScreen.add(bitmapField);
|
Button Field
ButtonField包含了用户选择来完成操作的按钮。使用ButtonField可以创建超出菜单的扩展交互的界面。
|
ButtonField mySubmitButton = new ButtonField("Submit");
ButtonField myResetButton = new ButtonField("Reset");
mainScreen.add(mySubmitButton);
mainScreen.add(myResetButton);
|
为了给button增加功能,扩展ButtonField并且覆写trackwheelClick()方法,以让它能完成一个操作来代替调用菜单。当用户点击button后为了接受消息,使用一个FieldChangeListener对象。为得到更多信息,参看78页的“监听UI对象的改变”.
Choice Field
Choice field类似于下拉列表。这里有2种choice field:包含整数的和包含可以转化为字符串的对象。
你也可以显示一组选项作为check box或者radio button。为了得到更多信息,参看45页的“option field”。
为了从ChoiceField里选择一个值,用户可以完成下面的操作:
- <!--[if !supportLists]-->点击field,并且按Space键。
- <!--[if !supportLists]-->按住Alt键,滚动滑轮。
- <!--[if !supportLists]-->打开菜单,选择Change Option。
|
类
|
描述
|
|
NumericChoiceField
|
NumericChoiceField是一个包含了一组数字的ChoiceField。NumericChoiceField实例典型的用在较少的数字范围内(到20个之多)。
NumericChoiceField myNumericChoice =
new NumericChoiceField( "Select a number: ",
1, 20, 10);
mainScreen.add(myNumericChoice);
注:对于大数量的数字,使用GaugeField,为得到更多信息,参看47页的“Gauge Field)。
|
|
ObjectChoiceField
|
ObjectChoiceField是一个包含了对象的ChoiceField。这个Field的所有对象必须实现Object.toStirng()以提供他们自己的字符串表现形式。
|
Option Field
OptionField允许用户从列表种选择条目。为允许用户从选择列表中选择多个条目,使用CheckBoxField。为允许用户从选择列表中仅选择一个条目,使用RadioButtonField。
|
类
|
描述
|
|
CheckBoxField
|
每个CheckBoxField是一个独立的对象,与其他的可选框无关。
CheckboxField myCheckbox =
new CheckboxField("First checkbox", true);
CheckboxField myCheckbox2 =
new CheckboxField("Second checkbox", false);
...
mainScreen.add(myCheckbox);
mainScreen.add(myCheckbox2);
|
|
RadioButtonField
|
多个RadioButtonField对象组合在一个RadioButtonGroup中,这样用户一次只能选择一个选项。
RadioButtonGroup rbGroup = new RadioButtonGroup();
RadioButtonField rbField = new RadioButtonField("First field");
RadioButtonField rbField2 = new RadioButtonField("Second field");
...
rbGroup.add(rbField);
rbGroup.add(rbField2);
...
mainScreen.add(rbField);
mainScreen.add(rbField2);
|
Date Field
在你的应用程序中,一个DateField显示当前的日期和时间。
|
类型
|
描述
|
|
DATE
|
显示年月日
|
|
DATE_TIME
|
显示年月日,时分秒
|
|
TIME
|
显示时分秒
|
当创建一个DateField时,调用System.currentTimeMillis()得到当前时间。
|
DateField dateField =
new DateField("Date: ", System.currentTimeMillis(),
DateField.DATE_TIME);
mainScreen.add(dateField);
|
Date Field缺省为可编辑的。为了创建一个用户不能编辑的Date Field,在其构造子中指定Field.READONLY参数。
将为可编辑的Date Field提供一个缺省的Change Options菜单项。
Edit Field
一个EditField允许用户在此Field里输入文本。AutoTextEditField, EditField, 和 PasswordEditField 都扩展了BasicEditField.
注:net.rim.device.api.ui.component.TextField类,扩展了Field类,并且是抽象的。实例化它的子类,例如RichTextField 或 EditField,就是创建一个显示文本或允许用户输入文本的UI Field。
你可以应用下面的过滤项(filter)到Edit Field中。
|
过滤项
|
描述
|
|
DEFAULT_MAXCHARS
|
限制field中字符的个数。对于Edit Field,字符的最大个数缺省为15。
|
|
FILTER_DEFAULT
|
这个是缺省的文本输入过滤项。当构造子需要此过滤项,但是你又不想应用任何特定的过滤项时,那么使用它。
|
|
FILTER_EMAIL
|
仅允许有效的internet消息地址字符(例如,用户可以仅输入一个@标记).它会自动将文本格式化为internet消息地址格式(例如,当用户第一次按Space键时,一个@符号会出现,用户接着按Space键,每次.’s也随之出现。
|
|
FILTER_HEXADECIMAL
|
仅允许数字和A到F的字母。
|
|
FILTER_INTEGER
|
仅允许数字和负号“-“。
|
|
FILTER_LOWERCASE
|
将字符转化为小写
|
|
FILTER_NUMERIC
|
仅允许输入数字
|
|
FILTER_PHONE
|
仅允许输入有效电话号码字符,数字,连接号(-),加号和减号,左括号和右括号,以及”x”.
|
|
FILTER_PIN_ADDRESS
|
仅接受在PIN地址上输入的有效字符。
|
|
FILTER_UPPERCASE
|
将字母转化为大写。
|
|
FILTER_URL
|
仅允许有效的URL字符。它也自动格式化field。(当用户按Space键时它将插入一个节点).
|
|
JUMP_FOCUS_AT_END
|
改变field的行为,以致当field获得焦点,并且用户试图滚动时,焦点移动到field的末端(代替移动到下一个field)。
|
|
NO_NEWLINE
|
忽略文本中的换行和回车,例如用户从其他地方拷贝和粘贴的文本。
|
|
类
|
描述
|
|
RichTextField
|
RichTextField类创建一个只读的Field,它可以体格式化为各种不同的字体以及样式,RichTextField虽然不可以编辑,但是可以获取焦点。
mainScreen.add(new RichTextField("RichTextField"));
|
|
BasicEditField
|
BasicEditField是EditField, 和 PasswordEditField的基类。
BasicEditField是一个可编辑的文本Field,它没有缺省的格式,但是却可以接受过滤。
BasicEditField bf =
new BasicEditField(
"BasicEditField: ",
"", 10, EditField.FILTER_UPPERCASE);
mainScreen.add(bf);
|
|
EditField
|
EditField是一个可以编辑的文本Field,它扩展了BasicEditField。EditField允许用户当问特殊的字符。例如,用户按住A键,并且滚动滑轮来选择各种样式的A字符以及Æ字符。EditField类接受样式,但是有些样式会让EditField失去其功能(例如EditField.FILTER_PHONE).
mainScreen.add(new EditField("EditField: ", "", 10, EditField.FILTER_DEFAULT));
|
|
PasswordEditField
|
PasswordEditField扩展了BasicEditField,提供下面的功能:
<!--[if !supportLists]-->l <!--[endif]-->让用户输入显示为星号(*)。
<!--[if !supportLists]-->l <!--[endif]-->自动文本(AutoText)(或其他自动格式化)不会应用。
<!--[if !supportLists]-->l <!--[endif]-->剪切或拷贝不支持
下面的样例使用了一个构造子,允许你为PasswordEditField提供了一个缺省的初始化值。
mainScreen.add(new PasswordEditField("PasswordEditField: ", ""));
|
|
AutoTextEditField
|
|