文档库 最新最全的文档下载
当前位置:文档库 › Android开发指南-用户界面

Android开发指南-用户界面

Android开发指南-用户界面
Android开发指南-用户界面

Android开发指南-用户界面

菜单特性Menu Features

下面是适用于大多数菜单项的一些其他的特性。

菜单组Menu groups

当往菜单中添加新项时,你可以选择把它包含在一个组中。一个菜单组是一些可以共享某些特征的菜单项的集合,比如它们是否可见,是否可用,或者可否复选(checkable)。

一个组由一个整数定义(或者一个XML里的资源ID)。当我们使用接受一个groupId参数的add()方法,比如add(int, int, int, int)添加项时,它将被添加到组中。

你可以通过setGroupVisible()显示或隐藏菜单组;通过启用或禁用这个组;以及通过setGroupCheckable()设置菜单项是否可以复选。

可复选菜单项Checkable menu items

任何菜单项可以被用来表示选项开关的接口。这可以通过一个checkbox来指示一个单独的选项,或者通过一组单选按钮来表示互斥选项。(查看右边的截屏)。

注意:在图标菜单中的菜单项不能显示复选框或单选按钮。如果你选择让图标按钮中的菜单项变成可复选,那你必须在开关状态变化时自动通过切换图标和文本来指示这个状态。

要让一个单独的项变成可复选,使用setCheckable()方法,如下:

menu.add(0, VIBRATE_SETTING_ID, 0, "Vibrate")

.setCheckable(true);

这将为这个菜单项显示一个复选框(除非这是个图标菜单)。当这个item被选中时,通常onOptionsItemSelected()会被调用。你应该在这里设置复选框状态。你可以用isChecked()来查询这个菜单项的当前状态和用setChecked()来设置复选状态。就像下面一样:

switch (item.getItemId()) {

case VIBRATE_SETTING_ID:

if (item.isChecked()) item.setChecked(false);

else item.setChecked(true);

return true;

...

}

为了创建一组互斥的单选按钮,只要简单的为每个菜单项分配相同的group ID并调用

setGroupCheckable()。在这个例子里,你不需要为每个菜单项调用setCheckable()方法,因为这个组被整体上设置为可复选。下面是在一个子菜单中创建两个互斥选项的例子:

SubMenu subMenu = menu.addSubMenu("Color");

subMenu.add(COLOR_MENU_GROUP, COLOR_RED_ID, 0, "Red");

subMenu.add(COLOR_MENU_GROUP, COLOR_BLUE_ID, 0, "Blue");

subMenu.setGroupCheckable(COLOR_MENU_GROUP, true, true);

在setGroupCheckable()方法里,第一个参数是我们想设置为可复选的group ID。第二个参数表示是否设置为可复选。最后一个参数代表这些菜单项是否互斥(如果设置为false,则所有的菜单项将会是复选框而不是单选按钮。当这个组设置为互斥时(单选按钮),每当一个新的项被选中时,所有其它的项的选择会自动被清除。

注意:可复选菜单项倾向于基于每次会话使用,而不保存到设备中。(例如,地图应用程序中的Map mode设置并不会被保存-截屏如上)。如果有一些应用程序设置你需要为用户保存它,那你应该使用首选项Preferences来保存数据,而通过一个PreferenceActivity来管理它们。

快捷键Shortcut keys

可以为菜单项添加字母或数字快捷键,setAlphabeticShortcut(char)方法(设置字母快捷键),setNumericShortcut(int)方法(设置数字快捷键),或

者setShortcut(char,int)(同时设置字母和数字)。非大小写敏感,比如:

menu.add(0, MENU_QUIT, 0, "Quit")

.setAlphabeticShortcut('q');

现在,当菜单打开时(或者按住菜单键),按”q”键将选择该菜单项。

这个快捷键将以菜单项的提示信息而显示在菜单项名称的下面(除了图标菜单项)。

注意:快捷键不能添加进一个上下文菜单项中。

菜单项意图Menu item intents

如果你已经阅读过应用程序基础Application Fundamentals,那么你应该多少知道一点Android 意图。它允许程序互相绑定,分享信息,以及合作执行用户任务。就像你的应用程序可以发送一个意图来启动浏览器,邮件客户端或者另外一个活动一样,你可以从菜单中执行这样的动作。有两种途径来做这件事:定义一个意图然后分配给一个单独的菜单项,或者定义一个意图并允许Android查找设备上的活动然后动态的为每个符合意图标准的活动添加一个菜单项。

请阅读意图和意图过滤器章节,以获取更多关于意图创建和应用程序提供服务方面的信息。

为一个单独的菜单项设置一个意图Set an intent for a single menu item

如果你想提供一个具体的菜单项来启动一个新的活动,那么你可以通过setIntent()方法具体地为这个菜单项定义一个意图。

比如,在onCreateOptionsMenu()方法里,你可以用一个意图定义一个新菜单项如下:

MenuItem menuItem = menu.add(0, PHOTO_PICKER_ID, 0, "Select Photo");

menuItem.setIntent(new Intent(this, PhotoPicker.class));

当这个菜单项被选中时,Android将自动启动这个活动。

注意:这并不会给你的活动返回一个结果。如果你希望返回一个结果,那么不要使用

setIntent()。相反,和通常情况一样在

onOptionsMenuItemSelected() or onContextMenuItemSelected()回调中处理并调用startActivityForResult().

动态添加意图Dynamically add intents

如果有潜在的多个活动和你的当前活动或所选择菜单项相关,那么这个应用程序可以动态添加菜单项来执行其他的服务。

在菜单创建过程中,定义一个意图,使用Intent.ALTERNATIVE_CATEGORY和/

或Intent.SELECTED_ALTERNATIVE类别,当前选择(如果有的话)的MIME类型,以及其他需求,和你打开一个新活动时想要满足一个意图过滤器一样。然后调用addIntentOptions()来让Android查找任何满足那些需求的服务并为你添加它们到菜单中。如果已安装的程序没有满足这个意图的,那么将不会有额外的菜单项被添加。

注意:SELECTED_ALTERNATIVE是用来处理屏幕当前选中元素的。所以,它应该仅当在onCreateContextMenu()或onPrepareOptionsMenu()里面创建菜单项时使用, 后者每

次打开选项菜单时会被调用。

下面是一个说明应用程序如何搜索附加服务来显示在它的菜单中的例子。

public boolean onCreateOptionsMenu(Menu menu){

super.onCreateOptionsMenu(menu);

// Create an Intent that describes the requirements to fulfill, to be included

// in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.

Intent intent = new Intent(null, getIntent().getData());

intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

// Search for, and populate the menu with, acceptable offering applications.

menu.addIntentOptions(

thisClass.INTENT_OPTIONS, // Menu group

0, // Unique item ID (none)

0, // Order for the items (none)

this.getComponentName(), // The current Activity name null, // Specific items to place first (none)

intent, // Intent created above that describes our requirements

0, // Additional flags to control items (none)

null); // Array of MenuItems that corrolate to specific items (none)

return true;

}

对于每个活动,如果其意图过滤器匹配我们所定义的那个意图,则将会添加一个菜单项,使用这个意图过滤器的android:label值作为菜单项的文本。这个addIntentOptions()方法也会返回所增加菜单项的数目。

请同时注意,当addIntentOptions()被调用时,它将重写第一个参数指定的所有菜单组里的菜单项。

如果想把你的活动的服务提供给其他应用程序菜单,那么你只需要和通常情况一样定义一个意图过滤器。只是需要确保在一个意图过滤器的元素的name属性中包含ALTERNATIVE和/或SELECTED_ALTERNATIVE值。比如:

...

android:name="android.intent.category.ALTERNATIVE" />

android:name="android.intent.category.SELECTED_ALTERNATIVE" /> ...

在意图和意图过滤器文章中有更多关于创建意图过滤器的描述。

要了解使用该技术的一个例子应用程序,可查看NotePad范例代码。

创建菜单 Creating Menus

菜单是任何应用程序的一个重要部分,提供了透露应用程序功能和设置的通用接口。Android为开发者提供了一个简单的编程接口来实现各种条件下的标准化应用程序菜单。

Android提供了三种基础菜单类型:

选项菜单Options Menu

这是一个活动的主菜单。通过按下设备菜单键来显示它。选项菜单包含两组菜单项:

图标菜单Icon Menu

这个是当用户按下菜单键时最初出现屏幕下方的item集合。它支持最多6个菜单项。

只有这些菜单支持图标而且这些菜单并不支持checkboxes或者radio buttons。

扩展菜单Expanded Menu

这是通过按“更多”菜单显现出来的一个竖向的项目列表。它仅当图标菜单过多时存在而且是由6个以及其它选项菜单组成。

上下文菜单Context Menu

这是一个浮动菜单列表,通常在你长时间按在一个视图上时出现(比如一个列表项)

子菜单Submenu

这是一个浮动菜单列表,通过在选项菜单或上下文菜单选择菜单项显露出来。不支持嵌套子菜单。

选项菜单Options Menu

这个选项菜单通过按设备菜单键打开。打开后,出现图标菜单,可包含6个菜单项。如果添加

多于6个菜单项,多出的部分将通过“更多”菜单项在扩展菜单中显示。扩展菜单项在多于6

个菜单项时自动添加。

选项菜单应该包含应用程序的基本功能以及任何必要的浏览项(例如,返回桌面或应用程序设置)。你还可以通过增加子菜单Submenus来组织主题和包含额外的菜单功能。

当菜单第一次被打开时,系统会调用活动onCreateOptionsMenu()回调函数。重写该方法并生成传递给你的这个菜单对象。你可以通过扩充定义在XML文件中的一个菜单资源或者通过为你想要的每一个菜单项调用add()方法生成这个菜单。这个方法增加一个菜单项MenuItem,并返回新创建的对象。你可以用返回的MenuItem来设置附加属性如图标,快捷键,意图以及这个菜单项的其它设置。

有多个add()方法。通常,你会使用接受一个itemId参数的那个。这是一个唯一的整数,允

许你在回调函数中识别这个item。

当一个菜单项从选项菜单中被选择时,你会接收到一个onOptionsItemSelected()回调。这个回调传给你选中的MenuItem。你可以通过请求itemId:getItemId()来识别它,这将返回add()方法分配的整数。一旦你识别了这个菜单项,就可以采取合适的动作。

下面是一个活动里的例子,其中我们创建了一个选项菜单并处理菜单项的选择:

/* Creates the menu items */

public boolean onCreateOptionsMenu(Menu menu) {

menu.add(0, MENU_NEW_GAME, 0, "New Game");

menu.add(0, MENU_QUIT, 0, "Quit");

return true;

}

/* Handles item selections */

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case MENU_NEW_GAME:

newGame();

return true;

case MENU_QUIT:

quit();

return true;

}

return false;

}

这个add()方法有四个参数:groupId, itemId, order, 和title。groupId允许你关联这个菜单到一个菜单组中(更多参见下面的菜单组Menu groups)-这个例中,我们忽略掉它。itemId是用来识别菜单项的唯一的整数,在回调函数中使用。order允许我们定义菜单的显示顺序-缺省情况下,

它们以添加时的顺序排列。title当然是菜单的名字(可以是一个字符串资源,为了本地化更加方便,建议你使用资源)。

提示:如果你有一些可以以一个标题归类的菜单项,考虑以子菜单Submenu的方式组织它们。增加图标Adding icons

图标也可以通过setIcon()函数被添加到菜单项中。

menu.add(0, MENU_QUIT, 0, "Quit")

.setIcon(R.drawable.menu_quit_icon);

修改菜单Modifying the menu

如果有些时候你想在选项菜单被打开的时候re-write它,可以

override onPrepareOptionsMenu()方法,该方法在每一次菜单被打开的时候调用。它将传递给你菜单对象,就像回调一样。这对于根据应用程序状态调整菜单选项很有用。

注意:当改变菜单项时,根据当前选择的item来这样做是一个不好的行为。记住,在触摸模式中,将不会有一个选择或聚焦的item。相反,当你想基于UI中的某个特定item来提供功能时,你应该使用一个Context Menu来完成这种行为。

上下文菜单Context Menu

Android的上下文菜单在概念上和PC软件的右键菜单类似。当一个视图注册到一个上下文菜单时,执行一个在该对象上的“长按”(按住不动差不多两秒钟)动作,将出现一个提供相关功能的浮动菜单。上下文菜单可以被注册到任何视图对象中,不过,最常见的是用于列表视图ListView 的item,在按中列表项时,会转换其背景色而提示将呈现上下文菜单。(电话联系人列表提供了关于这个特性的一个很好的例子)。

注意:上下文菜单项不支持图标或快捷键。

为了创建一个上下文菜单,你必须重写这个活动的上下文菜单回调函数:onCreateContextMenu()和onContextItemSelected()。在回调函数

onCreateContextMenu()里,你可以通过使用一个add()方法来添加菜单项,或者通过扩

充一个定义在XML中的菜单资源。然后,通过registerForContextMenu()为这个视图注册一个上下文菜单ContextMenu.

比如,下面的代码可以被用到Notepad应用程序中来为列表中的每一个注释添加一个上下文菜单:

public void onCreateContextMenu(ContextMenu menu, View v,

ContextMenuInfo menuInfo) {

super.onCreateContextMenu(menu, v, menuInfo);

menu.add(0, EDIT_ID, 0, "Edit");

menu.add(0, DELETE_ID, 0, "Delete");

public boolean onContextItemSelected(MenuItem item) {

AdapterContextMenuInfo info = (AdapterContextMenuInfo)

item.getMenuInfo();

switch (item.getItemId()) {

case EDIT_ID:

editNote(info.id);

return true;

case DELETE_ID:

deleteNote(info.id);

return true;

default:

return super.onContextItemSelected(item);

}

}

在onCreateContextMenu()中,除了给出将添加MenuItems的ContextMenu外,还需要给定选中的视图和一个上下文菜单信息ContextMenuInfo对象,该对象提供了选中对象的附

加信息。在本例中,onCreateContextMenu()没做什么特别的事-只是添加了一些菜单项。在onContextItemSelected()回调函数中,我们从MenuItem中请求AdapterContextMenuInfo,该对象提供当前选中项的信息。我们从中所要的只是这个选中项的列表ID,所以无论编辑还是删除一个注释,我们通过这个对象的https://www.wendangku.net/doc/cb16629600.html,字段来找到该ID。这个ID被传递给editNote()和deleteNote()方法来执行相应的动作。

现在,要为一个列表视图中的所有项注册上下文菜单,我们可以传递整个的列表视图对象给registerForContextMenu(View)方法:

registerForContextMenu(getListView());

记住,你可以传递任何视图对象来注册一个上下文菜单。这里,getListView()返回这个被用于Notepad应用程序的列表活动ListActivity中的列表视图对象。这样,这个列表中的任何item都被注册到这个上下文菜单。

子菜单Submenus

一个子菜单可以被添加进任何菜单中,但不能加入另外的子菜单中。当你的应用程序有很多功能可以按主题组织的时候,这将非常有用,就好比PC应用程序的菜单栏(文件,编辑,视图,等)。

子菜单通过addSubMenu()加入到已有的菜单中而创建。该函数会返回一个子菜单SubMenu对象(菜单Menu的一个扩展)。然后你可以通过调用add()方法给这个菜单添加其他项,例如:

public boolean onCreateOptionsMenu(Menu menu) {

boolean result = super.onCreateOptionsMenu(menu);

SubMenu fileMenu = menu.addSubMenu("File");

SubMenu editMenu = menu.addSubMenu("Edit");

fileMenu.add("new");

fileMenu.add("open");

fileMenu.add("save");

editMenu.add("undo");

editMenu.add("redo");

return result;

}

子菜单中选择项的回调动作将由父菜单的回调方法处理。比如上面的例子,子菜单中的选择将由onOptionsItemSelected()回调处理。

你也可以在XML中定义父菜单时增加子菜单。

在XML里定义菜单Define Menus in XML

就像Android用户界面布局一样,你可以在XML文件中定义菜单,然后在你菜单的onCreate...()回调函数中扩充它们。这使得你的应用程序代码简洁而且把更多的界面设计分离到XML文件中,这更容易形象化。

首先,在你的工程res/的目录下创建一个新的目录叫menu。你所有定义应用程序菜单的XML 文件都应该放在这里。

在一个菜单XML布局中,有三个合法的元素:

。item和group必须是菜单的子元素,而item元素还可以是group的子元素,并且另外一个菜单元素可以是一个item的子元素(来创建一个子菜单)。当然,任何文件的根元素必须是一个menu元素。

作为一个例子,我们将定义和在上面的选项菜单Options Menu章节中所创建的相同的菜单,我们首先在目录res/menu/里创建一个名为options_menu.xml的文件。

xmlns:android="https://www.wendangku.net/doc/cb16629600.html,/apk/res/android">

android:title="New Game" />

android:title="Quit" />

然后,在onCreateOptionsMenu()方法里,我们通过MenuInflater.inflate()方法扩充这个资源:

public boolean onCreateOptionsMenu(Menu menu) {

MenuInflater inflater = getMenuInflater();

inflater.inflate(R.menu.options_menu, menu);

return true;

}

getMenuInflater()方法返回我们活动上下文的MenuInflater。然后我们调用

inflate(),传递给它一个指向我们菜单资源的指针以及回调给出的菜单对象。

尽管和在onCreateOptionsMenu()创建菜单比较起来,上面的例子看起来做了更多的事情,但是如果处理更多的菜单项,这将省掉很多麻烦并让你的代码简洁。

你可以通过把item元素打包进一个group中来定义菜单组menu groups,然后通过在一个item中嵌入另外一个menu来创建子菜单。每个元素都支持必需的属性来控制快捷键,复选框,图标,以及更多特性。

要了解这些属性和更多的XML语法,请参见可用资源类型Available Resource Types中的相关主题。

Android开发指南-用户界面-对话框收藏

创建对话框Creating Dialogs

对话框通常是一个显示在当前活动前面的小窗口。下面的活动失去焦点而由对话框接受所有的用户交互。对话框通常被用来当做通知或者运行中的应用程序相关的短暂活动。

Android API支持下面的对话框对象类型:

警告对话框AlertDialog

这个对话框管理0,1,2,或3个按钮,和/或一个可包含复选

框和单选按钮的可选项列表。这个警告对话框能够组建大多数

用户界面而且是推荐使用的对话框类型。请查看下面的创建一

个警告对话框Creating an AlertDialog。

进度对话框ProgressDialog

用来显示一个进度轮或进度条。因此它是警告对话框的扩展,

它也支持按钮。请查看下面的Creating a ProgressDialog。

日期选择对话框DatePickerDialog

一个允许用户选择日期的对话框。请查看Hello DatePicker指

南。

时间选择对话框TimePickerDialog

一个允许用户选择时间的对话框。请查看Hello TimePicker指

南.

如果你想定制你自己的对话框,你可以在基础对话框对象或任何上面列举的子类对话框上进行扩展并定义一个新的布局。请查看下面的创建自定义对话框Creating a Custom Dialog章节。

显示对话框Showing a Dialog

对话框经常作为活动Activity的一部分来创建和显示。你通常应该从活动的onCreateDialog(int)回调方法里创建对话框。当你使用这个回调函数时,Android系统会有效的设置这个活动为每个对话框的所有者,从而自动管理每个对话框的状态并挂靠到活动上。这样,每个对话框继承这个活动的特定属性。比如,当一个对话框打开时,菜单键显示为这个活动定义的选项菜单,音量键修改活动使用的音频流。

注意:如果你决定在onCreateDialog()方法之外创建一个对话框,它将不会被附着到活动上。不过,你可以通过setOwnerActivity(Activity)把它附着到一个活动上。

当你想要显示一个对话框时,调用showDialog(int)方法并传递一个唯一标识这个对话框的整数。

当对话框第一次被请求时,Android从你的活动中调用onCreateDialog(int),你应该在这里初始化这个对话框Dialog。这个回调方法被传以和showDialog(int)相同的ID。当你创建这个对话框后,在方法的最后返回这个对象。

在对话框被显示之前,Android还调用了可选的回调函数onPrepareDialog(int, Dialog). 如果你想在每一次对话框被打开时改变它的任何属性,你可以定义这个方法。这个方法在每次打开对话框时被调用,而onCreateDialog(int)仅在对话框第一次打开时被调用。如果你不定义onPrepareDialog(),那么这个对话框将保持和上次打开时一样。这个方法也被传递以对话框的ID,和在onCreateDialog()中创建的对话框对象。

定义onCreateDialog(int)和onPrepareDialog(int, Dialog)回调函数的最佳方法是使用一个switch语句来检查传递进来的id参数。每个case应该检查一个唯一的对话框ID然后创建和定义相应的对话框。比如,想象一下一个游戏使用两个不同的对话框:一个用来指示这个游戏已经暂停而另一个来指示游戏结束。首先,为每个对话框定义一个整数:

static final int DIALOG_PAUSED_ID = 0;

static final int DIALOG_GAMEOVER_ID = 1;

然后,为每一个ID用一个switch case定义这个onCreateDialog(int)回调函数:

protected Dialog onCreateDialog(int id) {

Dialog dialog;

switch(id) {

case DIALOG_PAUSED_ID:

// do the work to define the pause Dialog

break;

case DIALOG_GAMEOVER_ID:

// do the work to define the game over Dialog

break;

default:

dialog = null;

}

return dialog;

}

注意:在这个例子里,case语句没有具体内容,因为这超出了本章讨论范围。

当是时候显示其中之一的对话框时,使用对话框ID调用showDialog(int):

showDialog(DIALOG_PAUSED_ID);

消除对话框Dismissing a Dialog

当你准备关闭对话框时,你可以通过对这个对话框调用dismiss()来消除它。如果需要,你还可以从这个活动中调用dismissDialog(int)方法,这实际上将为你对这个对话框调用dismiss()方法.

如果你想使用onCreateDialog(int)方法来管理你对话框的状态(就如同在前面的章节讨论的那样),然后每次你的对话框消除的时候,这个对话框对象的状态将由该活动保留。如果你决定不再需要这个对象或者清除该状态是重要的,那么你应该调用removeDialog(int)。这将删除任何内部对象引用而且如果这个对话框正在显示,它将被消除。

使用消除侦听器Using dismiss listeners

如果你希望你的应用程序在一个对话框消亡的时候执行一些流程,那么你应该附着一个on-dismiss侦听器到对话框上。

首先定义DialogInterface.OnDismissListener接口。这个接口只有一个方法,onDismiss(DialogInterface),将在对话框消亡的时候被调用。然后简单的传递你的OnDismissListener 实现给setOnDismissListener()。

然而, 请注意对话框也可以被“取消”。这是一个表明对话框被用户显示取消的特殊情况。这将在用户按“返回”按钮时发生,或者这个对话框显示的调用cancel()(也许通过对话框上的一个“取消”按钮)。当一个对话框被取消时,这个OnDismissListener 依然会被通知到,但是如果你希望在对话框被显示取消时被通知到(而不是通常的消除方式),那么你应该通过setOnCancelListener()注册一个DialogInterface.OnCancelListener。

创建警告对话框Creating an AlertDialog

一个警告对话框是对话框的扩展类。它能够构建大多数对话框用户界面并且是推荐使用的对话框类型。你应该在具备如下特性的时候使用它:

?一个标题

?一个文本消息

? 1个,2个或3个按钮

?一个可选项列表(可选的复选框或单选按钮)

为了创建一个警告对话框,使用AlertDialog.Builder子类。通过AlertDialog.Builder(Context)获取一个构造器然后使用这个类的公共方法来定义警告对话框的所有属性。当得到构造器后,通过create().方法来获取警告对话框对象。

下面的题目说明了如何使用AlertDialog.Builder类来定义不同的警告对话框属性。如果你在onCreateDialog()回调函数中使用下面的代码,你可以返回结果对话框对象来显示它。

增加按钮Adding buttons

为了创建一个如右图所示的包含并行按钮的警告对话框,使用set...Button()方法:

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setMessage("Are you sure you want to exit?")

.setCancelable(false)

.setPositiveButton("Yes", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int id) {

MyActivity.this.finish();

}

})

.setNegativeButton("No", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int id) {

dialog.cancel();

}

});

AlertDialog alert = builder.create();

首先,为这个对话框添加一个消息setMessage(CharSequence)。然后,开始函数链并设置该对话框为不能取消not cancelable(因此用户不能使用返回按钮关闭这个对话框)。对每个按钮,使用任一set...Button()方法,比如setPositiveButton(),该方法接受按钮名称以及一个定义用户选中按钮后所采取动作的DialogInterface.OnClickListener。

注意:你仅可以为这个警告对话框添加其中一种按钮类型。也就是,你不能包含多个“确定”按钮。这限制了可能的按钮数目只能是3个:确定,中立和否定。这些名字和你按钮的实际功能是技术上无关的,但是应该可以帮助你记录做了什么。

增加一个列表Adding a list

为了创建一个带有可选项列表的警告对话框,如右边所示,可使用setItems()方法:

final CharSequence[] items = {"Red", "Green", "Blue"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Pick a color");

builder.setItems(items, new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int item) {

Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();

}

});

AlertDialog alert = builder.create();

首先,用setTitle(CharSequence)方法给对话框添加一个标题。然后,添加用setItems()添加一个可选项列表,该列表接受一组显示的items和一个DialogInterface.OnClickListener来定义用户选中按钮后所采取动作。

增加复选框和单选按钮

要在对话框里创建一个多选项列表(checkboxes)或者单选项(radio buttons),可分别调用

setMultiChoiceItems()和setSingleChoiceItems()方法。如果你在onCreateDialog()回调函数中创建这些可选列表,Android会帮你管理列表状态。只要这个活动是激活的,对话框会记住之前选中的items,但如果用户退出这个活动,用户选择将丢失。

注意:为了在用户离开或暂停这个活动的时候能够保存选择,你必须通过活动生命期Activity Lifecycle来恰当的保存和恢复设置。为了永久保存选项,即使活动进程被完全终止,你需要使用数据存储Data Storage 技术。

要创建如右边所示的一个包含单选项列表的警告对话框,使用前面例子中相同的代码,不过需要把setItems()方法替换为setSingleChoiceItems()。

final CharSequence[] items = {"Red", "Green", "Blue"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Pick a color");

builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int item) {

Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();

}

});

AlertDialog alert = builder.create();

setSingleChoiceItems()的第二个参数是一个checkedItem整型数值,指示了基于0的缺省选择项的位置。“-1”代表不会有默认选择项。

创建进度对话框Creating a ProgressDialog

进度对话框ProgressDialog是AlertDialog类的一个扩展,可以为一个未定义进度的任务显示一个旋转轮形状的进度动画,或者为一个指定进度的任务显示一个进度条。这个对话框也能提供按钮,比如一个取消下载的按钮。

可以简单的通过调用ProgressDialog.show()方法来显示一个进度对话框。比如,可以很简单的得到右边显示的进度对话框,而不必通过onCreateDialog(int)回调管理这个对话框,如下所示:

ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",

"Loading. Please wait...", true);

第一个参数是应用程序上下文Context,第二个是对话框标题(此处为空),第三个是信息,最后这个参数表明进度是否是不确定的(这只和创建进度条有关,下一章会有描述)。

进度对话框的缺省类型是一个旋转轮,如果你想创建一个间隔进度,需要更多的代码,如下章所述。

显示进度条Showing a progress bar

使用动画进度条显示进度:

1.用类构造器初始化进度对话框,ProgressDialog(Context)。

2.用setProgressStyle(int)方法设置进度风格为"STYLE_HORIZONTAL"以及设置其它属性,比如消息。

3. 当你准备显示这个对话框时,调用show()或者从onCreateDialog(int)回调中返回ProgressDialog。

4. 你可以通过调用setProgress(int)设置当前进度百分比或者调用incrementProgressBy(int)方法增加

进度值。

比如,你的设置可能看起来像这样:

ProgressDialog progressDialog;

progressDialog = new ProgressDialog(mContext);

progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

progressDialog.setMessage("Loading...");

progressDialog.setCancelable(false);

设置很简单。大多数创建代码也用来更新进度。你可能意识到创建另外一个线程来完成这个进度报告的工作是有必要的,进度通过一个对象返回给活动的用户界面线程。如果你对如何通过一个Handler使用另外的线程不熟悉,请参见下面的例子:

Example ProgressDialog with a second thread

这个例子使用了另外一个线程来跟踪进程进度(计数到100)。这个线程在每次进度更新时通过一个句柄Handler发回一条消息Message。主活动然后更新进度对话框。

package com.example.progressdialog;

import android.app.Activity;

import android.app.Dialog;

import android.app.ProgressDialog;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

public class NotificationTest extends Activity {

static final int PROGRESS_DIALOG = 0;

Button button;

ProgressThread progressThread;

ProgressDialog progressDialog;

/** Called when the activity is first created. */

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(https://www.wendangku.net/doc/cb16629600.html,yout.main);

// Setup the button that starts the progress dialog

button = (Button) findViewById(R.id.progressDialog);

button.setOnClickListener(new OnClickListener(){

public void onClick(View v) {

showDialog(PROGRESS_DIALOG);

}

});

}

protected Dialog onCreateDialog(int id) {

switch(id) {

case PROGRESS_DIALOG:

progressDialog = new ProgressDialog(NotificationTest.this);

progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

progressDialog.setMessage("Loading...");

progressThread = new ProgressThread(handler);

progressThread.start();

return progressDialog;

default:

return null;

}

}

// Define the Handler that receives messages from the thread and update the progress final Handler handler = new Handler() {

public void handleMessage(Message msg) {

int total = msg.getData().getInt("total");

progressDialog.setProgress(total);

if (total >= 100){

dismissDialog(PROGRESS_DIALOG);

progressThread.setState(ProgressThread.STATE_DONE);

}

}

};

/** Nested class that performs progress calculations (counting) */

private class ProgressThread extends Thread {

Handler mHandler;

final static int STATE_DONE = 0;

final static int STATE_RUNNING = 1;

int mState;

int total;

ProgressThread(Handler h) {

mHandler = h;

}

public void run() {

mState = STATE_RUNNING;

total = 0;

while (mState == STATE_RUNNING) {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

Log.e("ERROR", "Thread Interrupted");

}

Message msg = mHandler.obtainMessage();

Bundle b = new Bundle();

b.putInt("total", total);

msg.setData(b);

mHandler.sendMessage(msg);

total++;

}

}

/* sets the current state for the thread,

* used to stop the thread */

public void setState(int state) {

mState = state;

}

}

}

创建自定义对话框Creating a Custom Dialog

如果你想为对话框做一个自定义的设计,你可以为对话框窗口创建自己的布局和部件元素。当你定义好布局后,传递根视图对象或者布局资源ID给setContentView(View)方法。

比如,创建如右图所示对话框:

1.创建一个XML布局以custom_dialog.xml保存:

xmlns:android="https://www.wendangku.net/doc/cb16629600.html,/apk/res/android"

android:id="@+id/layout_root"

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:padding="10dp"

>

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:layout_marginRight="10dp"

/>

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:textColor="#FFF"

/>

这个XML在一个LinearLayout里定义了一个ImageView和一个TextView.

2. 设置上面这个布局作为对话框的内容视图并为这个ImageView和TextView元素定义内容:Context mContext = getApplicationContext();

Dialog dialog = new Dialog(mContext);

dialog.setContentView(https://www.wendangku.net/doc/cb16629600.html,yout.custom_dialog);

dialog.setTitle("Custom Dialog");

TextView text = (TextView) dialog.findViewById(R.id.text);

text.setText("Hello, this is a custom dialog!");

ImageView image = (ImageView) dialog.findViewById(R.id.image); image.setImageResource(R.drawable.android);

实例化对话框后,用setContentView(int)设置你的自定义布局作为这个对话框的内容视图,以布局资源ID 作为参数。现在这个对话框有一个已定义的布局,你可以用findViewById(int)方法从布局中抓取视图对象。

3. 就这样了。你现在可以显示该对话框了,参见Showing A Dialog中的描述。

以基类对话框创建的对话框必须有一个标题。如果你不调用setTitle(),那么标题占用的空间保持为空,但仍然可见。如果你根本不想要一个标题,那你应该使用警告对话框AlertDialog来创建你的自定义对话框。然而,因为警告对话框可以很简单的通过AlertDialog.Builder类来创建,你并不需要访问上面使用的setContentView(int)方法。相反,你必须使用setView(View)。这个方法接受一个视图View对象,所以你需要在XML中扩充布局的根视图。

要扩充XML布局,用getLayoutInflater()或getSystemService()方法获取LayoutInflater,然后调用inflate(int, ViewGroup),这里第一个参数是布局资源ID而第二个参数是根视图的ID。在此处,你可以使用扩充布局来查找视图对象和为ImageView和TextView元素定义内容。然后实例化AlertDialog.Builder 并调用setView(View)为该对话框设置扩充布局。

下面是一个例子,在一个警告对话框中创建自定义布局:

AlertDialog.Builder builder;

AlertDialog alertDialog;

Context mContext = getApplicationContext();

LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER);

View layout = inflater.inflate(https://www.wendangku.net/doc/cb16629600.html,yout.custom_dialog,

(ViewGroup) findViewById(https://www.wendangku.net/doc/cb16629600.html,yout_root));

TextView text = (TextView) layout.findViewById(R.id.text);

text.setText("Hello, this is a custom dialog!");

ImageView image = (ImageView) layout.findViewById(R.id.image);

image.setImageResource(R.drawable.android);

builder = new AlertDialog.Builder(mContext);

builder.setView(layout);

alertDialog = builder.create();

在你的自定义布局中使用警告对话框可以让你利用警告对话框的内置特性比如管理按钮,可选列表,一个

标题,一个图标等。

想获取更多信息,请参考Dialog和AlertDialog.Builder类的相关文档。

Android开发指南-用户界面-事件处理收藏

处理用户界面事件Handling UI Events

在Android上,不止一个途径来侦听用户和应用程序之间交互的事件。对于用户界面里的事件,侦听方法就是从与用户交互的特定视图对象截获这些事件。视图类提供了相应的手段。

在各种用来组建布局的视图类里面,你可能会注意到一些公共的回调方法看起来对用户界面事件有用。这些方法在该对象的相关动作发生时被Android框架调用。比如,当一个视图(如一个按钮)被触摸时,该对象上的onTouchEvent()方法会被调用。不过,为了侦听这个事件,你必须扩展这个类并重写该方法。很明显,扩展每个你想使用的视图对象(只是处理一个事件)是荒唐的。这就是为什么视图类也包含了一个嵌套接口的集合,这些接口含有实现起来简单得多的回调函数。这些接口叫做事件侦听器event listeners,是用来截获用户和你的界面交互动作的“门票”。

当你更为普遍的使用事件侦听器来侦听用户动作时,总有那么一次你可能得为了创建一个自定义组件而扩展一个视图类。也许你想扩展按钮Button类来使某些事更花哨。在这种情况下,你将能够使事件处理器event handlers类来为你的类定义缺省事件行为。

事件侦听器Event Listeners

事件侦听器是视图View类的接口,包含一个单独的回调方法。这些方法将在视图中注册的侦听器被用户界面操作触发时由Android框架调用。下面这些回调方法被包含在事件侦听器接口中:onClick()

包含于View.OnClickListener。当用户触摸这个item(在触摸模式下),或者通过浏览键

或跟踪球聚焦在这个item上,然后按下“确认”键或者按下跟踪球时被调用。

onLongClick()

包含于View.OnLongClickListener。当用户触摸并控制住这个item(在触摸模式下),

或者通过浏览键或跟踪球聚焦在这个item上,然后保持按下“确认”键或者按下跟踪球

(一秒钟)时被调用。

onFocusChange()

包含于View.OnFocusChangeListener。当用户使用浏览键或跟踪球浏览进入或离开这

个item时被调用。

onKey()

包含于View.OnKeyListener。当用户聚焦在这个item上并按下或释放设备上的一个按

键时被调用。

onTouch()

包含于View.OnTouchListener。当用户执行的动作被当做一个触摸事件时被调用,包括

按下,释放,或者屏幕上任何的移动手势(在这个item的边界内)。

onCreateContextMenu()

包含于View.OnCreateContextMenuListener。当正在创建一个上下文菜单的时候被调

用(作为持续的“长点击”动作的结果)。参阅创建菜单Creating Menus章节以获取更

多信息。

这些方法是它们相应接口的唯一“住户”。要定义这些方法并处理你的事件,在你的活动中实现这个嵌套接口或定义它为一个匿名类。然后,传递你的实现的一个实例给各自的View.set...Listener()方法。(比如,调用setOnClickListener()并传递给它你的OnClickListener 实现。)

下面的例子说明了如何为一个按钮注册一个点击侦听器:

// Create an anonymous implementation of OnClickListener

private OnClickListener mCorkyListener = new OnClickListener() { public void onClick(View v) {

// do something when the button is clicked

}

};

protected void onCreate(Bundle savedValues) {

...

// Capture our button from layout

Button button = (Button)findViewById(R.id.corky);

// Register the onClick listener with the implementation above button.setOnClickListener(mCorkyListener);

...

}

你可能会发现把OnClickListener作为活动的一部分来实现会便利的多。这将避免额外的类加载和对象分配。比如:

public class ExampleActivity extends Activity implements OnClickListener {

protected void onCreate(Bundle savedValues) {

...

Button button = (Button)findViewById(R.id.corky);

button.setOnClickListener(this);

}

// Implement the OnClickListener callback

public void onClick(View v) {

Android简单的登陆界面的设计开发

通信实训报告 -Android移动平台开发 学院:信息工程学院 班级: 学号: 姓名:

实训内容: 一.1.Andriod的简介 Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。目前,最新版本为Android 2.4 Gingerbread 和Android 3.0 Honeycomb。 Android是基于Linux开放性内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 Android早期由原名为"Android"的公司开发,谷歌在2005年收购"Android.Inc"后,继续对Android系统开发运营,它采用了软件堆层(software stack,又名软件叠层)的架构,主要分为三部分。底层Linux内核只提供基本功能,其他的应用软件则由各公司自行开发,部分程序以Java编写。2011年初数据显示,仅正式上市两年的操作系统Android已经超越称霸十年的塞班系统,使之跃居全球最受欢迎的智能手机平台。现在,Android系统不但应用于智能手机,也在平板电脑市场急速扩张,在智能MP4方面也有较大发展。采用Android系统主要厂商包括台湾的HTC,(第一台谷歌的手机G1由HTC生产代工)美国摩托罗拉,SE等,中国大陆厂商如:魅族(M9),华为、中兴、联想、蓝魔等。 2.Android构架图 二.1软件下载 Android SDK,网址是https://www.wendangku.net/doc/cb16629600.html,. JDK的下载地址https://www.wendangku.net/doc/cb16629600.html,/javase/downloads/widget/jdk6.jsp。Eclipse的下载网址是https://www.wendangku.net/doc/cb16629600.html,/downloads/ 2.Android开发环境搭建

Android人机界面(UI)设计规范(带目录)

Android 人机界面设计规范 1Android 设计的依据 1.1 框架结构及流程 是什么使得android 有着独特的用户体验? 后台处理支持多任务功能 正在进行和事件驱动的提示信息 通过Widgets 和live folders 来实现实时信息的预览 用户想用时,任一应用程序都可以挑选和选择 android 不是关于程序的,它是关于活动,把任务分层, 1.2 架构基础 硬件平台 android 设备代表的是硬件和软件的完美组合。硬件辅助导航操作,并给android 提供更多更好的功能。当菜单没有开启,要把屏幕最大化时,菜单按钮可以在屏幕上提供更多的内容。返回按钮允许使用返回堆(back stack)。 竖屏与横屏 一般来说,用户界面开发竖屏与横屏。在新横屏也仍存在于新的Android 手机中。99%的android 布局支持横屏。 焦点和菜单 在触摸模式里没有焦点,只有轨迹球。Android 平台里没有鼠标焦点。确定你从未显示焦点。主菜单应该包括全部功能;它们与活动联系一起形成整体。菜单上的图标按重要性排序。如果有多于5 个图标,使用点击more menu 菜单来查看那些不太重要的菜单项。上下文菜单(长按)集中在一个特定对象。 总是把那些与所选项最相关的行为放在长按菜单的顶部。 需要记住的几点: 设计时要考虑速度和简洁 尽量分层来分等级 屏幕上的活动尽量最小 使用下载进度条,下载数据时,而不是让用户等待去看一个加载完全的页面。 考虑活动流而不是线性行为 1.3 屏幕上的行为

android 设计了特定的行为方式。在你的应用程序里利用好这一点。应该坚持android 行为的标准,避免混淆用户。 1.4 表达 细节使得产品集中在细节。程序的美学会帮助你集中注意在那些应用体验核心的关键任务上。API DEMO 是开始你的工具包的好地方。 2 用户界面原则 这部分试图讲述创造一个好的用户界面的一些基本的交互设计原则。这些原则是基本的,不止能应用于android 的用户界面设计,也可以应用于其他。苹果建议开发者花费60%的开发时间来进行设计工作。下面的用户界面原则将为好的设计提供一个基础。 2.1 隐喻 隐喻是构建一个基于操作任务心智模型的模块;用它们来传递应用程序的概念和功能。基于真实世界的应用对象可以帮助用户很快的理解该应用程序。当你设计你的应用程序时,要注意andriod 中存在的隐喻,不要重新定义它们。同时,检查你的应用程序执行的任务,看是否有些自然隐喻你可以使用。 2.2 反映用户的心智模型 用户已经有了一个来描述你的程序正在进行的任务的心智模型。这个心智模型产生于真实世界经验、其它软件和一般电脑基本知识的结合。比如说,用户在真实世界里有写字、寄信的经验,也会产生特定的期待,像写一封新的信,选一个接受者,然后寄出信。一个忽略用户心智模型的电子邮件程序用起来会很困难和不舒服。这是因为程序强加给用户一个不熟悉的概念模型,而不是建立一个用户已有的知识经验模式。 在设计程序用户界面之前,试着去发现你的用户的心智模型,这样帮助用户去执行任务。心智模型中内在的隐喻,它代表了任务的概念组成。在写信这个例子中,隐喻包括信件、邮包和信封。在涉及到照片的任务的思考模式中,隐喻包括照片、照相机和专辑。我们要努力地发现用户的期望,包括任务组成、组织、窗口布局的工作流、菜单和工具栏组织、控制面板的使用。 要通过努力地何必把个下面的特征与用户心智模型相融合: 熟悉性 用户的心智模型主要是建立在经验的基础上 简单化 一项任务的心智模型通常是流线型,关注任务的基本组成部分。尽管对于一个给定的任务有很多可选的细节,但是基本的组成部分占大部分,并且不会占用用户的注意。 可利用性Availability

第4章 Android用户界面设计

视图组件的使用模式 常用组件 高级组件 提示框与警告对话框

就是Android应用程序的开发过程。一般过程是先通过XML布局文件或Java代码创建界面布局,设定组件显示样式,随后获取UI组件对象,并处理组件事件响应。 视图组件的定义 资源的访问 生成视图组件资源标识 视图组件的引用 视图组件的事件响应 组件的常用属性

1.1视图组件的定义 使用XML布局文件定义视图组件 使用Java代码定义视图组件(不推荐)

1.1视图组件的定义 使用XML布局文件定义视图组件 Android平台为大多数视图组件以及其子类提供了XML标记,可通过XML布局文件中的标记来定义视图组件。XML中的每个元素代表了一个组件,即元素名称对应相应的Java类。

1.1视图组件的定义

相关文档
相关文档 最新文档