Android 3.0正式发布后的一点与技术无关的感想

今天Android SDK发布了新的版本,主要内容即是Android 3.0的Honeycomb。 官方网站的Dev Guide也作了很大幅度的调整。稍微看了一下,主要是增加了新的API Level 11中的内容,原有的部分也是比以前更有条理了。 不过,这也意味着自己之前的翻译不得不做比较大的调整。

新的SDK还增加了一个XVGA分辨率的皮肤,自己的笔电分辨率刚好到XVGA而已(虽然说可以缩小显示尺寸…)。由于各种因素,近期应该还不会涉足平板用的程序。

其实自己之前版本的要素还没有完全摸透,现在又增加了那么多新内容,还真是不得了……再有几天就要开学了,不得不更加抓紧时间才行。

自从接触Android开发后,就觉得是在和Google赛跑。新的内容推出的速度似乎是有些太快了。当然我这样的业余开发者有这种感觉也是很正常的吧。况且和那些牛人比起来,自己花在玩上的时间还是太多了。

没办法,慢慢来吧。只要不断前进就好。

Android中创建并使用上下文菜单(Context menu)

代码与范例:

说明:正如用户界面一文中所提到的,Android支持长按项目弹出上下文菜单。上下文菜单相当于桌面系统中的鼠标右键菜单,设计合理的上下文菜单可以提高程序的可用性。通常上下文菜单配合ListActivity使用。使用上下文菜单需要覆盖onCreateContextMenu和onContextItemSelected这两个方法。此外,必须要在活动的onCreate()方法中注册上下文菜单。使用以下语句即可:

Android用日常事项管理软件 Routine

一直以来对GTD相关的内容比较有兴趣,也试过各种各样的电子GTD工具,可是一直没有特别满意的。之前一直用的是Android上的Gtasks。这是一个不错的软件,但是含有广告、反应速度慢、有太多多余功能以及偶尔会出现条目丢失的Bug等问题还是让人觉得不尽人意。还试过Jorte,这款软件的优点是界面美观,不足之处则是反应速度略慢,设置过于繁琐对我而言无用的功能还是太多。由于这些原因,决定自己动手写一个简洁的GTD工具,也就是本文要介绍的Routine。

相比已有的数量众多的GTD工具,Routine有以下特点:

  • 稳定可靠:由于结构简单,而最大限度地确保了程序的稳定性。
  • 反应迅速:由于没有多余功能,因而Routine得以快速地启动、关闭。
  • 功能简洁:专注于GTD本身即可。
  • 界面美观:专门针对Xperia机型设定了背景,而非不少Android程序所使用的黑色背景。不过只有在Xperia机型上才会显示,以避免在原生Android系统中的不协调。
  • 没有广告:对于这种需要经常使用的程序如果加入广告还真是影响速度、增加网络流量还影响心情。所以Routine没有也不会有广告。
  • 多国语言支持:简体中文、繁体中文、英语、日语。其中英语和日语受自己水平所限难免不地道,敬请指正。

目前Routine可以在Android Market的效率类应用程序中找到,搜索Routine、ルーチン或者pub:BREEZE即可。如果需要一款简单好用的GTD工具,不妨试试看Routine吧。

Android Market页面:

http://market.android.com/details?id=org.breezesoft.routine

最后是一些Routine的程序截图:

创建菜单

菜单是程序重要的一部分,它提供给用户一个熟悉的接口以进入程序功能或是设置。Android提供了一个简单的框架以供为应用程序提供标准的菜单。

有三种类型的应用程序菜单:

选项菜单

当用户按下菜单键后出现的一个程序中主要的菜单项目的集合。如果程序运行在Android3.0或更新的版本时,可以将菜单项目直接置于操作条作为快捷方式,也就是“操作项目”。

上下文菜单

当用户长按一个注册了上下文菜单的视图时出现的浮动菜单项目列表。

子菜单

当用户按下一个包含嵌套菜单的菜单项目时出现的浮动菜单项目列表。

本文档将说明创建每一种菜单的方式,如何使用XML来定义菜单的内容以及程序中响应用户选择项目的回馈方法。

创建菜单资源

不应当在程序代码中实例化菜单,而要在XML菜单资源中定义一个菜单和它的所有项目,并在程序代码中解压(作为可编程对象载入)该菜单资源。通过菜单资源来定义菜单是推荐的做法,因为这样可以从程序代码中分离菜单内容。通过XML也能更容易地可视化菜单的结构和内容。

要创建菜单资源,要在工程的res/menu目录下创建XML文件并通过以下元素构建菜单:

<menu>

定义包含菜单项目的菜单。<menu>元素必须是文件的根节点以包含一个或多个<item><group>元素。

<item>

创建一个在菜单中表示单个项目的MenuItem。该元素可以包含潜逃<menu>元素以创建子菜单。

<group>

一种可选的<item>元素的不可见的容器。它可以分类菜单项目以共享如活动状态和可见性等属性。参见“菜单组”一节。

这里有一个名为game_menu.xml的菜单范例:

该范例定义了一个包含两个项目的菜单。每一个项目包含这些属性:

android:id

项目唯一的资源ID,让程序可以在用户选择时识别项目。

android:icon

作为项目图标的drawable资源的引用。

android:title

作为项目标题的字符串的引用。

还可以在<item>中包含更多的属性,其中一些可以定义项目如何出现在动作条中。关于XML语法和菜单资源的属性的更多信息,参阅“菜单资源引用”。

解压菜单资源

可以在程序代码中通过MenuInflater.inflate()解压菜单资源(将XML资源转换为可编程对象)。比如,下面的代码在onCreateOptionsMenu()中解压了前面定义的game_menu.xml,用以作为活动的选项菜单:

getMenuInflater()方法返回给活动一个MenuInflater。这个对象可以调用inflate()来解压一个菜单资源使之成为一个Menu对象。在本例中,game_menu.xml定义的菜单资源被解压为Menu后被传递至onCreateOptionsMenu()。(这一选项菜单的回馈方法将在下一节中详细讨论。)

创建选项菜单

选项菜单中应当包含有基本的活动行为和必要的导航项目(比如,一个用以打开程序设置的按钮)。选项菜单中的项目可以通过两种不同的途径访问:MENU键或者是动作条(仅用于运行Android 3.0或更高版本的设备)。

在使用Android 2.3或更低的系统的设备上,选项菜单出现于屏幕底部,如图1所示。当被打开后,选项菜单首先可见的部分是图标菜单。它包含了前六个菜单项目。如果选项菜单中添加了六个以上的项目,Android会将第六个和之后的项目放入溢出菜单,在用户点击“More”菜单项目时被打开。

Figure 1
图1. 浏览器中选项菜单的截图

在Android 3.0或更高版本中,选项菜单中的项目被置于位于活动顶部的动作条中,取代了传统的标题栏的位置。选项菜单中所有的项目默认是置于溢出菜单中的,用户可以点击动作条右部的菜单图标来打开。不过,也可以把一些菜单项目作为“动作项目”直接置于动作条以便快速选择,如图2所示。

 

图 2. Email程序中动作条的截图,有两个选项菜单中的动作项目,以及一个溢出菜单。

当Android系统第一次创建选项菜单时,会调用活动的onCreateOptionsMenu()方法。在活动中覆盖这个方法,加入要传递给这个方法的Menu,按照之前在“解压菜单资源”中所说的方式解压菜单资源。比如说:

也可以在代码中加入菜单,使用add()来添加项目至菜单。

注意:在Android 2.3 或更低的版本中,系统在用户第一次打开选项菜单时才调用onCreateOptionsMenu()来创建它,但是在Android 3.0及以后,系统在活动被创建时就会马上创建选项菜单以设置动作条。

响应用户动作

当用户从选项菜单(以及动作条中的动作项目)中选择了一个菜单项目,系统会调用活动的onOptionsItemSelected()方法。该方法传递用户选择的MenuItem。可以通过调用getItemId()来识别菜单项目,它会返回菜单项目的唯一ID(它是在菜单资源中通过android:id属性定义,或者使用add()方法给定的一个整数)。可以将此ID与已知的菜单项目配对以执行正确的动作。例如:

在这个例子中,getItemId()请求所选菜单项目的ID,switch语句则比较这些ID和XML资源中分配的菜单项目资源ID。当一个switch case成功配对菜单项目,它返回true以表示菜单选择已被处理。否则,如果父类可以处理项目的话默认语句将传递菜单项目至其父类。(如果是直接扩展于Activity类的话,父类会返回false,不过比起直接返回false,传递未被处理的菜单项目至其父类是一种比较好的做法)。

此外,Android 3.0增加了可以在XML菜单资源中通过使用android:onClick属性定义菜单项目单击行为的功能。因此不需要使用onOptionsItemSelected()。使用android:onClick属性,可以指定用户选择菜单项目时调用某一方法。活动之后会调用在android:onClick属性中指定的方法以接受一个单独额MenuItem参数——当系统调用该方法时,会传递所选择的菜单项目。

Tip:如果程序包含多个活动,并且一些活动提供了相同的选项菜单的话,可以考虑创建一个活动只使用onCreateOptionsMenu()和onOptionsItemSelected()方法。之后将这个类扩展用于共用该选项菜单的活动。这样一来,只需要管理一组处理菜单动作的代码即可,其他每一个后继类都会继承其菜单行为。

如果想要在某一个后继活动中增加菜单项目,就在该活动中覆盖onCreateOptionsMenu()。调用super.onCreateOptionsMenu(menu)以创建菜单,之后使用menu.add()增加新菜单项目。也可以覆盖父类的行为来设置单个的菜单项目。

在运行时改变菜单项目

一旦活动被创建,onCreateOptionsMenu()方法只会像前面描述的那样被调用一次。系统会在活动被销毁前保持和重用在该方法中定义的菜单。如果想在创建后的任意时间改变选项菜单,就必须覆盖onPrepareOptionsMenu()方法。它将传递当前存在的Menu对象。当希望根据程序的当前状态来删除、添加、禁用或启用菜单项目时,这种做法会很有用。

在Android 2.3或更低版本上, 系统会在每一次用户打开选项菜单时调用onPrepareOptionsMenu()。

在Android 3.0或更高版本,则需要在想要更新菜单时调用invalidateOptionsMenu(),因为菜单是始终打开的。系统之后会调用onPrepareOptionsMenu()来更新菜单项目。

注意:不能改变基于当前处于焦点下的视图的选项菜单的项目。在触摸模式下(即用户没有使用轨迹球或是指点杆),视图无法成为焦点,因此不应该将焦点作为改变选项菜单项目的基础。如果想要创建对视图上下文敏感的菜单项目,请使用上下文菜单。

如果开发平台是Android 3.0或更高,确保阅读过“使用动作条”一文。

创建上下文菜单

上下文菜单从理念上来说类似于在PC上用户“右键单击”时显示的菜单。应该提供给用户上下文菜单以执行对于用户界面上属于某一特定项目的操作。在Android上,上下文菜单会在用户“长按”(按下不放)某一项目时被显示。

可以为任意View创建上下文菜单,不过上下文菜单通常被用于ListView中的项目。当用户长按ListView中的一个项目并且该列表被注册提供一个上下文菜单时,该列表项目会改变背景色以告知用户上下文菜单是可用的——它用橙黄色转变为白色并打开上下文菜单。(通讯录程序展示了这一特性。)

为了让一个View提供上下文菜单,比如给该视图“注册”一个上下文菜单。调用registerForContextMenu()并传递想要添加上下文菜单的视图。当该视图收到长按操作时,它会显示上下文菜单。

要定义上下文菜单的外观和行为,需要覆盖活动的上下文菜单回馈方法,即onCreateContextMenu()和onContextItemSelected()。

注册一个ListView

如果活动使用ListView并且希望所有的列表项目都提供上下文菜单,就要通过传递该ListView至registerForContextMenu()来为所有的项目注册上下文菜单。比如,如果正在使用ListActvity,就像这样注册所有的列表项目:

registerForContextMenu(getListView());

举例来说,这里有一个使用了context_menu.xml菜单资源的的onCreateContextMenu():

MenuInflater用于从菜单资源中解压上下文菜单。(也可以使用add()来添加菜单项目。)回馈方法参数包括用户所选择的View和提供所选项目附加信息的ContextMenu.ContextMenuInfo对象。可以用这些参数来判定应当创建哪一个上下文菜单,不过在这个例子中,活动所使用的所有上下文菜单都是相同的。

之后当用户从上下文菜单中选择了一个项目时,系统将调用onContextItemSelected()。这里有一个例子来说明如何处理选中的项目:

这段代码的结构与创建选项菜单的例子中的相似,getItemId()询问了所选项目的ID,一个switch语句来匹配菜单资源中所定义的项目ID。和选项菜单的例子一样,默认语句调用了父类以备处理当前类无法处理的项目。

在本例中,所选的项目是ListView中的一个项目。为了实现对所选项目的操作,程序需要知道所选项目的列表ID(即在ListView中的位置)。为了取得此ID,程序调用了getMenuInfo(),来返回包含id域中所选项目列表ID的一个AdapterView.AdapterContextMenuInfo对象。本地方法editNote()deleteNote()方法将接受该列表ID来对指定列表ID的数据进行操作。

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

创建子菜单

子菜单是一种用户在选择另一菜单中的项目时打开的菜单。可以向任何菜单(除了子菜单)添加子菜单。子菜单在程序有大量可以按主题来组织的功能时很有用,就好象是PC程序的菜单栏(文件、编辑、视图等)。

当创建菜单资源时,可以通过添加一个<menu>元素作为一个<item>的子元素来创建子菜单,例如:

当用户从子菜单中选择了一个项目时,父级菜单的项目被选择时的回馈方法会接受这一事件。例如,如果上级菜单是一个选项菜单,那么onOptionsItemSelected()方法会在子菜单项目被选择时被调用。

也可以用addSubMenu()来动态地想已存在的菜单添加SubMenu。它会返回新的SubMenu对象,可以通过add()来对其添加子菜单项目。

其他菜单特性

对于大多数菜单来说还可以应用其他一些菜单特性。

菜单组

菜单组是共享某些特性的菜单项目的集合。将它们分成组后,可以:

  • 通过setGroupVisible()显示或隐藏所有项目
  • 通过setGroupEnabled()启用或禁用所有的项目
  • 通过setGroupCheckable()来设定是否所有项目都是可标记的

可以通过在菜单资源内的<group>元素内嵌套<item>元素以创建菜单组或是通过add()方法来指定一个组ID。

这里是一个包含了组的菜单资源的例子:

组中的那些项目似乎和那不在组中的第一个项目看起来是一样的——所有三个菜单内的项目是同级关系。不过,可以通过引用组ID和前面提到的方法来调整组中的两个项目的特性。

可标记菜单项目

对独立选项设置复选框或是对互斥选项设置单选框的话,菜单可以作为一种有用的开启或关闭选项的接口。图3展示了具有可单选项目的子菜单。

图 3.一个具有可选中项目的子菜单的截图

注意:图标菜单(来自于选项菜单)中的菜单项目不能设置复选框或是单选框。如果希望让图标菜单中的项目可被选中,必须在每次状态改变时通过改变图标和/或文字来手动指定选中状态。

可以使用<item>元素中的android:checkable属性为单个菜单项目定义选中行为,或使用<group>元素中的android:checkableBehavior属性来为整个组设置行为。比如,这个菜单组中的所有项目都可以单选:

android:checkableBehavior属性接受下列值其中之一:

single

组中只有一个项目可被标记(单选框)

all

所有项目可被标记(复选框)

none

没有项目可被标记

可以使用<item>元素中的android:checked属性来给项目设定默认标记状态,并在代码中用setChecked()方法来改变它。

当一个可标记项目被选中时,系统将调用特定的项目选择方法(比如onOptionsItemSelected())。在这里必须设定复选框的状态,因为复选框或是单选框不会自动改变其状态。可以用isChecked()获取项目当前状态(在用户选中之前)之后用setChecked()来设定其选中状态。例如:

如果不这样设定选中状态,项目(复选框或是单选框)的可见状态则会在用户选中时才改变。当设置了状态后,活动会保存项目的选中状态,这样之后用户打开菜单时,所设定的选中状态将是可见的。

注意:可选中菜单项目仅用于单次活动,不会再程序被销毁后保存。如果程序包含希望保存的设置,应当使用“共享偏好(Shared Preferences)”来存储数据。

快捷键

如果用户的设备有物理键盘,那么可以通过<item>元素中的android:alphabeticShortcutandroid:numericShortcut属性添加键盘字母/数字快捷键以支持对选项菜单中项目的快速选择。也可以用setAlphabeticShortcut(char)和setNumericShortcut(char)方法。快捷键对大小写敏感。

比如,如果应用“s”字符作为“保存(save)”菜单项目的字母快捷键,那么当菜单打开(或是用户按住菜单键)并且用户按下“s”键时,菜单项目“保存”就被选中。

快捷键作为一种提示被显示在菜单项目里,位于菜单项目名称之下(不过图标菜单中则是只有在用户按住菜单键时才会显示)。

注意:菜单项目的快捷键只能用于有物理键盘的设备。快捷键不能被添加到上下文菜单中的项目。

动态添加菜单意图

有时会希望菜单项目通过一个Intent来启动一个活动(无论这个活动属于自身所在的程序还是其他的程序)。当确定想要使用的意图并且有一个用以初始化该意图的特定菜单项目时,可以在恰当的项目选中方法中(比如onOptionsItemSelected()回馈方法)通过startActivity()来执行该意图。

不过,如果不确定用户的设备中包含可以处理该意图的程序的话,由于意图可能不能启动一个活动,所以就要增加一个在被调用时会生成一个无功能的菜单项目的菜单项目。为了实现这一效果,Android允许当在设备上发现可以处理该意图的活动时再向菜单动态添加菜单项目。

为了增加基于可接受一个意图的活动的菜单项目:

  1. 定义一个类别为CATEGORY_ALTERNATIVE和/或CATEGORY_SELECTED_ALTERNATIVE的意图,以及其他所需的内容。
  2. 调用Menu.addIntentOptions()。Android之后会搜索可执行该意图的程序并将其添加至菜单。

如果没有安装满足该意图的程序,就不会添加任何的菜单项目。

注意:CATEGORY_SELECTED_ALTERNATIVE用于处以屏幕上当前选中的元素。因此,只应当在当在onCreateContextMenu()创建Menu时使用。

例如:

每一个被发现提供了匹配所定义的意图的意图过滤器的活动将被添加一个菜单项目。意图过滤器的android:label的值会被作为菜单项目的标题,程序的图标则作为菜单项目的图标。addIntentOptions()方法会返回所添加的菜单项目的数量。

注意:当调用addIntentOptions()时,它会覆盖所有的由第一个参数指定的菜单组的菜单项目。

允许活动被添加至其他菜单

可以使自己的活动提供为其他程序所用的服务,这样自己的程序就可以被其他活动包含在菜单中(即前述内容的角色互换)。

为了能被包含在其他程序菜单中,需要和通常一样定义一个意图过滤器,不过必须在意图过滤器类别中包含CATEGORY_ALTERNATIVE和/或CATEGORY_SELECTED_ALTERNATIVE的值。例如:

可以在“意图和意图过滤器”文档中阅读更多关于意图过滤器的书写。

参见Note Pad范例代码以了解一个使用该技术的范例程序。

本页部分内容根据Android Open Source Project创作并共享的内容修改,并在知识共享 署名2.5许可协议中所述条款的限制下使用。

Android中使用OpenGL显示背景层透明度PNG图片

代码:

说明:使用这两句语句就可以在渲染时将PNG图片的背景透明化。注意PNG必须是32位的。如果不使用这两句,PNG图片则是显示黑色背景。

Android中OpenGL ES贴图无法显示问题的可能原因

最近在Android中使用OpenGL时遇到了这样的问题:一切代码没有问题,模拟器上也运行正常,但是在实机上就会出现贴图错误,纹理无法显示,只有灰白的底色。

对于这个问题找了很久的解决方法,都没有成功。最后发现其实是文件夹名称的问题。贴图文件原来是保存于drawable文件夹下的,并没有根据Dpi而建立多个文件夹,以为这样就会默认使用drawable文件夹内的资源。对于模拟器而言确实如此,但是对于实机就会出现问题。解决方法是建立drawable-nodpi文件夹,至少对我的情况来说问题就得到了解决。

另外看到的其他的可能原因还有贴图本身的问题,比如说文件尺寸过大、边长不是2的n次方等。我在自己的X10上测试了一下,边长确实有着前述的限制,不过即使是1024依旧可以正确显示,可见对文件大小的要求并不严苛。经测试1024×1024分辨率32位的PNG没有问题。

声明布局

wrap_content 使视图自动调节尺寸到内容所需的大小布局(layout)是一个活动的用户界面的结构。它定义了布局结构并包含了所有将向用户呈现的元素。可以通过两种途径声明布局:

  • 在XML中声明UI元素。Android提供了一组直观的XML词汇,它与View类及其子类(比如部件和布局所要使用的)对应。
  • 在运行时实例化布局元素。程序可以通过代码创建View和ViewGroup对象(并设置其属性)。

Android框架可灵活地使用以上一种或两种方法来声明并管理程序界面。比如,可以在XML中声明程序的默认布局,像是屏幕上显示的元素及其属性。之后可以在程序中添加代码以在运行时修改包括XML中所声明的屏幕物件的状态。

  • Eclipse的ADT插件提供了XML的布局预览——打开XML文件后选择Layout标签。
  • 还可以试着用层次查看器工具(Hierarchy View Tool)来调试布局——它显示了布局的属性值,以间距/边缘指示器来画出框架,并在通过模拟器或实机调试时渲染整个视图。
  • layoutopt工具可以快速分析布局和层次中的效率低下或其他问题。

在XML中声明UI的优势在于可以更好地分离程序显示与控制行为的代码。UI描述不属于程序代码。意味着不必修改源代码并重编译就能修改UI。比如,可以为不同屏幕方向、不同屏幕尺寸与不同语言创建多个XML布局。另外,在XML中声明布局使UI的可视化变得更为容易,也就更容易调试。因此,本文档着眼于讲授如何通过XML声明布局。如果对于在运行时实例化View对象的话,可以参考ViewGroup和View类的内容。

通常,用以声明UI元素的XML词汇和结构、类与方法的命名紧密相关,元素名称对英语类名,属性名称对应于方法。事实上,这一对应关系非常直接以至于可以猜出XML属性对应的类方法,或猜出一个给定的XML元素对应于哪一个类。不过,注意并非所有词汇都是相同的。在一些情况下,命名上有些小差异。比如,EditText元素有一个text属性,它对应的是EditText.setText()

Tip:可以在”常用Layout对象“一文中了解更多不同的布局类型。在”Hello Views“教程中有关于如何构建不同布局的一系列教程。

编写XML

使用Android的XML词汇,可以像用HTML创建网页一样通过一系列的嵌套元素快速地设计UI布局与其中包含的屏幕元素。

每一个布局文件必须包含一个View或ViewGroup对象作为根元素。一旦定义了根元素,就可以添加其他的布局对象或是部件作为其子元素,逐渐构造出能够用于定义布局的视图层次。比如,下面是一个XML布局,它使用了垂直LinearLayout并含有一个TextView和一个Button:

在XML中声明了布局之后,以.xml后缀保存该文件与Android项目的res/layout/文件夹,这样它就能被正确编译。

为了方便,UI相关的类的API参考文档列出了与类的方法对应的可用的XML属性,以及继承属性。

要了解更多关于可用的XML元素和属性以及XML文件的格式的信息,参阅“布局资源”。

稍后将讨论这里出现的每一个属性。

载入XML资源

在编译程序时,每一个XML布局文件会被编译为一个View资源。需要在该活动的onCreate()方法中使用程序代码来载入布局资源。通过调用setContentView(),以R.layout.layout_file_name的形式传递这个引用给布局资源。比如,如果XML布局被保存为main_layout.xml,那么应该像这样将它读入活动:

活动中的onCreate()回馈方法在活动被启动时被Android框架调用(参见“应用程序基础”中的关于生命周期的讨论以了解更多)。

属性

每一个View和ViewGroup对象支持其自有的XML属性。有些属性专用于某一View对象(比如,TextView支持textSize属性),但这种属性也会被扩展于这个类的View对象所继承。一些属性对所有View对象都适用,因为它们继承于根View类(比如id属性)。同时,其他的属性被看作是“布局参数”,在View对象的ViewGroup父对象中定义用以描述View对象特定的布局位置。

ID

任何View对象都有一个整数ID与之关联,以在层次树种唯一确定该View。当程序在编译时,ID作为整数被引用,不过ID却是作为字符串被分配给布局XML文件的。这是一个对所有View都适用的XML属性(由View类定义),将被经常使用。ID在XML标签中的语法格式如下:

字符串头部的@符号表明XML语法分析器应该把ID字符串的剩余部分识别为ID资源并分析与扩展它。加号(+)意味着这是一个新的资源名,必须被创建并添加至资源中(在R.java文件里)。还有其他许多Android框架提供的ID资源。在引用Android资源ID时,不需要使用加号,但必须像这样加上android包的命名空间:

由于有了android包的命名空间,现在可以引用android.R资源类中的ID,而不仅仅是本地资源类。

为了在程序中创建视图并引用它,通常采用这样的方式:

1、在布局文件中定义一个视图/部件,之后分配其一个专有的ID:

2、然后创建该视图对象的一个实例,并从布局中获取它(通常是在onCreate()方法中):

当创建一个RelativeLayout时为视图对象定义ID是很重要的。在相对布局(relative layout)中,同层次视图可以通过引用其唯一的ID来相对地定义它们之间的布局。

在整棵层次树中ID不需要是唯一的,但在被搜索的这部分中它需要是唯一的(不过由于通常会搜索整棵树,所以最好尽可能设定唯一的ID)。

布局参数

被命名为layout_XXXX的XML布局属性为View定义了其布局参数以适合于其所在的ViewGroup。

每一个ViewGroup类有一个扩展于ViewGroup.LayoutParams的嵌套类。这个子类包含了定义每一个子视图适合于视图组的尺寸和位置的正确类型。如下图所示,父视图组为每一个子视图(包括子视图组)定义了布局参数。

注意每一个LayoutParams子类都有其自有的赋值语法。每一个子元素必须定义适合于其父元素的LayoutParams,不过可以为它的子元素定义不同的参数。

所有的视图组包含有宽度和高度参数(layout_widthlayout_height),每一个试图都需要定义它们两者。许多LayoutParams还包含可选的边距等参数。

可以通过精确的单位来制定宽度和高度,不过往往不这样做。更常见的做法是用一下常量之一来设置宽度或高度:

  • wrap_content 使视图自动调节尺寸到内容所需的大小
  • fill_parent (在API Level 8中重命名为match_parent)使视图变为其父视图所允许的最大尺寸

通常,不推荐用绝对单位比如像素来定义布局的宽度和高度。改用相对度量方式比如密度无关像素单位(dp),wrap_content,或fill_parent是更好的方式,因为这样可以帮助确保程序可以在不同屏幕尺寸的设备上正确显示。可用的度量方式在“可用资源”文档中被定义。

布局位置

一个视图占有一块矩形区域。视图有一个通过一对左侧顶部坐标表示的位置,以及通过宽度和高度表示的两个维度。位置和维度的单位是像素。

可以通过调用getLeft()和getTop()方法来获得一个视图的位置。前者将返回视图所占矩形区域的左侧或者说X坐标,后者返回该矩形的顶部或者说Y坐标。这两种方法返回的位置都与其父视图相关。比如,如果getLeft()返回20,就意味着该视图处于其直接父视图左侧边缘起向右20像素的位置。

另外,有一些便利的方法可以用来避免不必要的计算,即getRight() 和getBottom()。这些方法返回视图矩形区域的右侧和底部坐标。比如,调用getRight()就类似于进行了getLeft() + getWidth()的计算。

尺寸、间隙和边距

视图的尺寸由宽度和高度表示。一个视图实际上有两组宽度和高度的数值。

第一组是测量宽度(measured width)测量高度(measured height)。它们订立了一个视图在其父视图内的大小。可以通过调用getMeasuredWidth()和getMeasuredHeight()来获取它们的值。

第二组是宽度高度,有时候也被称为绘制宽度绘制高度。这两个维度是视图在绘制和布局后在屏幕上的实际尺寸。它们的值有可能和测量宽度和高度不同。宽度和高度可以通过调用getWidth()和getHeight()获得。

为了测量一个视图的尺寸,需要考虑它的间隙(padding)。可以用像素表示视图上下左右的间隙。可以用一定像素的间隙来代替视图的内容。比如说,值为2的左侧间隙可以将视图的内容自左侧边缘向右推2个像素。可以用setPadding(int, int, int, int)方法来设定间隙,而通过getPaddingLeft()、getPaddingTop()、getPaddingRight()和getPaddingBottom()方法可以获得间隙的值。

尽管一个视图可以定义间隙,不过它不支持任何类型的边距(margin)。但视图组支持边距。参考ViewGroup和ViewGroup.MarginLayoutParams以获得进一步的信息。

关于维度的更多信息,请参见“维度的值”。

← 返回“用户界面”

本页部分内容根据Android Open Source Project创作并共享的内容修改,并在知识共享 署名2.5许可协议中所述条款的限制下使用。

Android 2.3中文简介

北京时间今天凌晨Google发布了Android最新的版本2.3。本文将以官方文档为基础对这一新版本做一个简单介绍。

Android 2.3 平台

API Level: 9

对于开发者来说,Android2.3现在已经能够作为SDK组件下载。它们包括了Android库,一些系统图片,模拟器皮肤等,不过没有包含外部库。

API 概览

接下来将对Android2.3中的新要素做技术概览,包括一些新功能和框架API的一些变化。更加具体的内容请参见Android Developer网站

  • 基于SIP的VoIP
  • 新版本包括了一个SIP协议栈以及框架API,使得开发者能够编写互联网电话应用。使用这个API的程序可以提供语音呼叫而不必处理分组管理等细节问题,它们将由Android 2.3的SIP服务来处理。具体的内容请参见Android Developer网站。

  • 近场通讯(NFC)
  • Android2.3包括了一个NFC栈以及框架API,它允许支持NFC的设备读取NDEF标签中的信息。Android2.3提供了一个底层的NFC服务,设备一旦在范围内发现一个NDEF标签,系统就会广播一个意图。

  • 螺旋传感器等
  • Android2.3开始支持一些新的传感器。螺旋仪、旋转感应、线性加速仪和重力感应等。开发者利用这个传感器可以快速流畅地识别出设备的位置和运动状态。

  • 多摄像头支持
  • 程序现在可以使用设备上的任何一个摄像头来拍照或是录制视频。

  • 可混合音效
  • Android2.3开始支持单音轨或是全局音效,包括低音加强、均衡器和回声效果等。

  • 下载管理器
  • 新版本提供了一个新的下载管理器来处理HTTP下载。程序可以要求一个URI被下载到某一文件,然后下载管理器会在后台处理这项工作,并会在下载出错、系统重启等时重试下载。

  • 严格模式(StrictMode)
  • 为了帮助开发者监视并提高程序的性能,Android2.3提供了新的系统工具StrictMode。它能捕获并通知开发者程序运行过程中意外发生的的会降低程序性能的磁盘或网络活动。开发者可以据此决定是否有必要修改这些问题。

  • UI框架
  • 滚动至底部/顶端的提示
    当滚动至视图端部的时候会有动画效果提示用户。
    触摸过滤
    可以增加对确定交易、授权允许等敏感触摸操作时的安全性。
    另外经过改良的还包括事件管理和触摸动作管理、文字选择控制、活动控制、通知文字及图表的风格和WebView。

  • 对超大尺寸屏幕的支持
  • 增加了xlarge屏幕尺寸的选项。

  • 图像
  • 增加了OpenGL ES 2.0中的 glDrawElements() 及glVertexAttribPointer()的支持。
    对VY12像素格式提供支持。

此外,这次升级还对Content Provider、Location、存储、Package管理、电话等一系列内容进行了修改和改良。限于篇幅在此不多说明,从官方网站可以得到更为详细的介绍。

而对于用户来说,Android2.3主要有以下改进:

  • 更为简洁高速的UI。
  • 更加方便快捷的文字输入。
  • 单击实现的文字选中、复制和粘贴。
  • 增强的电源管理功能。
  • 对应用程序更方便的控制。
  • 新的通讯和管理方式,包括近场通讯、网络电话、下载管理和多摄像头支持。

Android中调用资源中的图片

代码及范例:

说明:调用资源中res/drawable中的图形文件pic.*并绘图。该图形文件可以是jpg或png等格式。

Android中获取设备屏幕分辨率

代码及范例:

说明:
通过这段代码可以获取屏幕具体的分辨率数值,方便针对FWVGA/WVGA或FWQVGA/WQVGA这些分辨率相差不大的设备做UI的微调。也可以直接以屏幕分辨率为依据从整体上对UI进行适配。