WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章手机编程BlackBerryBlackBerry 应用程序开发者指南 第一卷:基础--第3章 创建用户接口(UI)

BlackBerry 应用程序开发者指南 第一卷:基础--第3章 创建用户接口(UI)
作者:佚名  来源:本站整理  发布时间:2008-3-14 21:52:28

作者: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设备编写应用程序时,使用下面2UI 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或其任一子类,FullScreenMainScreen的类。

描述

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个监听接口使程序接收和响应用户交互:TrackWheelListenerKeyboardListnenerScreen类和其子类都实现了这些方法。

提供screen导航(navigation

BlackBerry应用程序为用户提供一个菜单来完成操作。避免使用按钮(Button)或其他占据Screen空间的UI组件。

:按滑轮访问菜单。

当创建一个FullScreenScreen,在构造子里指明DEFAULT_MENUDEFAULT_CLOSE参数来提供缺省的导航。

FullScreen fullScreen = new FullScreen(DEFAULT_MENU | DEFAULT_CLOSE);

参数

描述

DEFAULT_MENU

这个参数增加一个缺省的菜单,它包含了不同的菜单项,这依赖域用户的上下文环境。例如,如果一个EditField获得焦点,将显示CutCopyPaste菜单项。所有已选择的域提供SelectCancel 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类通过使用它的子类,DialogStatus,来提供创建对话框和状态Screen的特性。Popup screen不会压入到显示栈中,为了显示一个popup screen,调用Dialog.ask(int)Status.show().

为了控制对话框的布局,使用DialogFieldManager对象,为了得到更多的信息,参看50页的为一个PopupScreeen指定布局

为了显示一个对话框,使用下面的一个参数来调用Dialog.ask():

参数

描述

D_OK

显示一个字符串,并且提示用户点击OK

D_SAVE

实现一个字符串,并且提示用户点击SaveDiscard,或者CancelEscape取消

D_DELETE

显示一个字符串,并且提示用户点击Delete或者CancelEscape撤销

D_YES_NO

显示一个字符串,并且提示用户点击YesNo

 

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 JDEnet.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文件,不能超过63000字节。

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类似于下拉列表。这里有2choice field:包含整数的和包含可以转化为字符串的对象。

你也可以显示一组选项作为check box或者radio button。为了得到更多信息,参看45页的option field

为了从ChoiceField里选择一个值,用户可以完成下面的操作:

  • <!--[if !supportLists]-->点击field,并且按Space键。
  • <!--[if !supportLists]-->按住Alt键,滚动滑轮。
  • <!--[if !supportLists]-->打开菜单,选择Change Option

描述

NumericChoiceField

NumericChoiceField是一个包含了一组数字的ChoiceFieldNumericChoiceField实例典型的用在较少的数字范围内(到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

仅允许数字和AF的字母。

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

BasicEditFieldEditField, PasswordEditField的基类。

BasicEditField是一个可编辑的文本Field,它没有缺省的格式,但是却可以接受过滤。

BasicEditField bf =

    new BasicEditField(

"BasicEditField: ",

       "", 10,           EditField.FILTER_UPPERCASE);

mainScreen.add(bf);

EditField

EditField是一个可以编辑的文本Field,它扩展了BasicEditFieldEditField允许用户当问特殊的字符。例如,用户按住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