本文档描述了如何使用应用部件提供者发布应用小部件。关于创建自己的应用部件宿主来容纳应用部件,请参考应用部件宿主。
如何设计自己的小部件的信息,请阅读小部件设计向导。
要创建应用小部件,你需要如下:
AppWidgetProviderclass 实现。 定义可以根据广播事件让你以编程方式与应用部件交互的基础方法。通过它,你将将收到应用部件更新,启用,禁止,和删除的广播。
此外,你可以实现一个应用部件配置活动。这是一个可选的活动。它在用户添加你的应用部件时启动,并且让他或她可以在创建时修改应用部件设置。
在清单中声明应用部件
元素需要android:name属性,它指定了应用组件使用的AppWidgetProvider。
元素指定AppWidgetProviderInfo资源并需要如下属性:
android:resource - 指定AppWidgetProviderInfo资源位置。
AppWidgetProviderInfo定义了应用部件的必要特性,例如最小布局尺寸,它的初始布局资源,多长时间更新应用部件,和(可选的)创建时启动的配置活动。使用一个单独的元素在XML资源中定义AppWidgetProviderInfo对象并奖它保存在工程的res/xml/文件夹。
这里是属性的一个总结:
查看应用部件设计引导了解更多关于调整应用部件大小的信息。
minResizeWidth和minResizeHeight属性指定了应用部件的绝对最小尺寸。这些值应该指定低于该值应用部件会难以识别或者不可用的大小。使用这些属性允许用户将大小调整为可能小于minWidth和minHeight属性的大小。安卓系统 3.1版本 引入。
updatePeriodMillis属性定义了应用部件框架应该多长时间通过调用onUpdate回调方法来从AppWidgetProvider请求更新。实际的更新不保证正好在这个时间发生,并且我们建议尽可能少地更新——也许不超过1小时一次以节省电量。你可能想让用户在配置中调整频率——有些人可能想要一个自动计数器每15分钟更新一次,或一天仅更新4次。
initialLayout属性指向定义应用部件布局的布局资源。
previewImage属性指定了应用部件在配置后将是什么样子的预览,它是用户选择应用部件时所看到的东西。如果没有提供,用会换而看到你的应用启动图标。 这个字段对应于AndroidManifest.xml文件中元素的android:previewImage属性。更多关于usingpreviewImage的讨论,参阅选择预览图像。安卓3.0版本引入。
resizeMode属性指定调整部件大小的规则。 你可以使用这个属性来让主屏幕小部件可以在水平,和素质,或同时两个方向上调整方向。用户按住部件来显示它的大小调节手柄,然后拖拽水平和/或垂直手柄来改变其占用布局单元格的大小。该属性的值包括“horizontal(水平)”,“vertical(垂直)”,和"none(无)"。想要声明部件为水平和垂直方向可调节大小,将该值设为“horizontal|vertical”。安卓系统3.1版本。
minResizeWidth属性指定部件可以调整的最小宽度(单位dps)。这个字段在大于最小宽度或未启用宽度大小调整(参考resizeMode)时无效。安卓系统4.0版本引入。
initialKeyguardLayout属性指向锁屏应用部件布局的布局资源。 这与android:initialLayout的工作方式相同,这种方式提供了应用部件初始后可以立即显示的布局并且可以更新该布局。安卓系统4.2版本引入。
创建应用部件布局
如果你熟悉布局,那么创建应用部件布局是简单的。但是,你必须知道应用部件布局是基于RemoteViews的,它不支持各种布局和视图部件。
和如下部件类:
RemoteView也支持ViewStub,它是一个不可见的,大小为0的视图,你可以在运行时延迟为它填充布局资源。
部件通常不应该延伸到屏幕边缘并且不应该在视觉上与其他部件齐平,因此你应该在你的部件框架(2)四周所有边上增加边距。
写一个单独的拥有应用于早期平台版本的自定义边距,且在安卓4.0或更高版本没有多余边距的布局是容易的:
创建一个如下的布局,它为自己的边距引用了尺寸资源:
res/values/dimens.xml:
另一种选择是简单地在默认情况下建立额外的边距到9宫格拉伸图片(译者注:横竖分成9份,中间5格是可重复像素的图片,一般用于常用的窗体背景)背景资源中,并为API级别14(译者注:就是安卓4.0版本,这是它的相应的API版本),或之后的版本提供没有边距的9宫格图片。
你必须在AndroidManifest(参考上面的在清单文件中声明应用部件)中使用元素将AppWidgetProvider类实现声明为广播接收者。
onUpdate这个方法被调用以在每经过一段间隔更新应用部件,这段间隔由AppWidgetProviderInfo(参考上面的添加AppWidgetProviderInfo元数据小节)中的updatePeriodMillis属性定义。这个方法也在用户添加该应用部件时调用,因此它应该执行一些必要的设置,例如定义视图的事件处理和必要时创建一个临时的服务。但是,如果你声明了一个配置活动,那么在用户添加应用部件时不会调用该方法,但是它会被后续的更新调用。用户配置活动有责任在配置完成后执行首次更新。(参考上面的创建应用部件配置活动)
这个回调函数在API级别16引入(安卓4.1版本)。如果你实现了这个回调函数,确保你的应用不会依赖它,因为它不会在旧的设备上被调用。
onEnabled(Context)这个方法在应用部件的实例首次被创建时调用。例如,如果用户添加了两个你的应用部件的实例,该方法仅在第一次添加时调用。如果你需要打开一个新的数据库或执行其他需要为所有应用部件实例执行一次的设置,那么这是做这件事的好地方。
onReceive(Context, Intent)这个方法在每次广播的时候被调用并且在上述个回调方法之前。你通常不需要实现这个方法,因为默认AppWidgetProvider实现过滤了所有应用部件广播并调用上述相应的方法。
AppWidgetProvider仅定义了onUpdate方法用于定义一个启动活动的挂起意图然后使用setonClickPendingIntent(int, PendingIntent)将它附加到应用部件的按钮上。注意,它包含了一个循环,遍历appWidgetIds中的每一个元素,这是标识这个提供者创建的每个应用部件的ID数组。 以这种方式,如果用户创建应用部件的多个实例,那么他们都会同时更新。但是, 只有一个updatePeriodMillis的周期(译者注:这里就是更新的时间间隔,原词:schedule,大意是计划的时间表,我的理解是要表达为计划的周期,这里直接省略为周期)将被应用于所有应用部件的实例。例如,如果更新周期定义为两小时,然后另一个部件的实例在第一个之后添加了一小时,那么他们都会按照第一个定义的间隔更新并且第二个更新间隔会被忽略(他们都会每两小时更新,而不是每一小时)。
接收应用部件广播意图
创建应用部件配置活动
配置活动应该在安卓清单文件中声明一个标准的活动。但是,它会被应用部件宿主使用ACTION_APPWIDGET_CONFIGURE操作启动,因此该活动需要接受这个意图。例如:
注意:该活动使用了全路径名称空间,因为它将在你的包外面被引用。
应用部件宿主调用配置活动并且配置活动总该返回一个结果。结果应该包含启动该活动意图传递的应用部件ID(保存在意图额外信息的EXTRA_APPWIDGET_ID(译者注:就是要用getExtra凭这个ID获取的数据,由setExtra设置))。
在下面的小节中的代码片段会看到如何从该配置返回结果和更新应用部件的例子。
当应用部件使用配置活动时,该活动有责任在配置完成后更新应用部件。你可以通过向应用部件管理者直接请求更新。
提示:当你的配置活动首次打开时,设置活动结果为RESULT_CANCELED,这样,在用户在完成之前退出,应用部件宿主会被通知配置被取消并且应用部件不会被添加。
设置预览图片
这显示了你将如何在XML中指定这些设置:
在锁屏中启用应用部件
默认情况下,每个应用部件都支持放置在主屏幕上,因此"home_screen"是android:widgetCategory属性的默认值。如果你的应用部件可以用于锁屏,那么添加"keyguard"值:
一旦你知道了部件的分类,就可以选择读取不同的基础布局,设置不同的属性,等等。例如:
大小调整向导
锁屏部件的宽度总会填充整个提供的空间。对于锁屏部件的高度,你有如下选择:
在手机的竖直模式中,"small"定义为解锁界面要显示时的剩余空间。
如果部件标记自己为可垂直调节大小,那么该部件在显示解锁界面的水平模式的手机上的高度显示为"small"。其他所有情况,部件缩放到填充全部有效高度。
安卓3.0版本为应用部件引入了集合。这些应用部件类型使用RemoteViewsService来显示由远端数据支持的集合,例如来自内容提供者数据。由RemoteViewsService提供的数据显示在使用如下视图类型的应用部件中,我们将称他们为”集合视图:“
GridView 在2唯滚动网格中显示条目的视图。举个例子,看下书签应用部件。
AdapterViewFlipper 适配器支持的简单ViewAnimator,它在两个以上的视图间变化。一次仅显示一个子视图。
RemoteViewsService是允许远端适配器请求RemoteViews对象的服务。RemoteViewsFactory是集合视图(例如,ListView,GridView等等)和它的核心数据间的适配接口。这是StackView部件示例中你用来实现服务和接口的样板代码的例子。
本小节的代码摘录是从StackView部件示例中摘出:
用户可以划开(5)应用部件上面的视图以显示下一个或上一个视图。这是一个内置的StackView行为。
如果用户点击上面的视图,应用部件会显示Toast消息”点击了视图n“这里的n是点击视图的序号(位置)。要了解更多这是如何实现的信息,参考给单独条目添加行为。
要实现带有集合的应用部件,你要遵循一些将用来实现任何应用部件的基础步骤。下面的小节描述了你需要执行的另外的步骤用以实现带有的应用部件。
除了在清单中声明应用部件列出的需求之外,要是带有集合视图的应用部件绑定到RemoteViewsService成为可能,你必须在清单文件中使用BIND_REMOTEVIEWS权限声明服务。这阻止了其他应用随意访问你的应用部件数据。例如,当创建使用usesRemoteViewsService填充集合视图的应用部件时,该清单项可能看起来像这样:
带有集合的应用部件的布局
注意空视图必须是其空视图代表空状态的集合视图的相邻视图(译者注:这里是描述的是列表里没数据时,屏幕什么都没有的情况,这是可以为这类集合使用一个空视图,并列的放一起就行。这里表达的意思是只有集合需要空试图的时候才能在旁边放个空视图。例如,一个只有一个文本”请拖拽刷新“的空视图。)。
带有集合的应用部件的AppWidgetProvider类
例如,下面是StackView部件如何实现onUpdate方法来设置RemoteViewsService为应用部件集合的远端适配器的:
数据持久化
如上所述,RemoteViewsService子类要提供RemoteViewsFactory用以填充集合视图。
RemoteViewsService实现的主要内容是它的RemoteViewsFactory,如上所述。
实现RemoteViewsFactory接口的自定义类要为应用部件提供集合条目的数据。为了做到这点,它结合了你的应用部件条目XML布局文件和一个数据源。这个数据源可以是从数据库到简单的数组的任何事物。在StackView部件示例中,数据源是WidgetItems的数组。RemoteViewsFactory用作连接数据与远端集合视图。
当你首次创建工厂时系统调用onCreate。这是你创建任何数据源的连接和/或游标的地方。例如StackView部件示例使用onCreate初始化一个WidgetItem对象的数组。当你的应用部件激活时,系统使用他们在数组中的索引位置来访问这些对象和它们所包含要显示的文本。
RemoteViewsFactory的方法getViewAt返回一个对应于数据集中特定位置的数据的远端视图对象。下面是StackView部件示例中RemoteViewsFactory实现的一段摘录:
上面的小节为你展示了如何为应用部件集合绑定数据。但是如果你想要在集合视图中为每个单独的条目动态的行为要做什么那?
本节使用StackView部件示例来描述如何为单独条目添加行为。在StackView部件示例中,如果你点击了上面的视图,应用部件显示了Toast消息”点击了视图n,“这里的n是点击视图的索引(位置)。下面描述了它是如何工作的:
建立一个挂起意图模板
这个类还接收用户点击视图时发送的广播。它在onReceive方法中处理这个事件。如果意图的操作是TOAST_ACTION,那么该应用部件将为当前视图显示一个Toast消息。
RemoteViewsFactory必须对每个集合条目创建一个填充意图。这使得区分单独的点击特定条目的操作成为可能。然后填充意图与挂起意图模板结合以决定点击条目时将要执行的最终意图。
下面的图展示了更新发生时,使用了集合的应用部件中发生的流程。它展示了应用部件代码如何与RemoteViewsFactory交互,和你可以如何触发更新:
译者注:这里不支持代码,所以没有显示出来。
百度首发地址:《android中文开发向导》
