前言
在Android3.0中,增加了大量的APP Widgets功能,在本文中将详细介绍它们。
一,设置预览图片
在Android 3.0版本中,增加了
previewImage
属性,它用于指明 App Widget的预览图片,它将在用户选中该App Widget的图标,打算添加该App Widget时,进行显示,以便用户了解该App Widget的界面。如果没提供预览图标的话,显示的将是你的App Widget的启动图标。该属性和AndroidManifest.xml中的<receiver>元素的android:previewImage的属性一致。你可以在XML定义该属性,如
示例1
示例1:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" ... android:previewImage="@drawable/preview"> </appwidget-provider>
Android emulator提供了一个叫做"Widget Preview"的APK应用程序,以便创建你的App Widgets的previewImage。
为了创建你的App Widgets的previewImage, 首先启动"Widget Preview"的这个应用程序, 然后选择需要制作previewImage的app widget,接着再按照提示在你的App Widget的Configuration Activity对其App Widget进行配置, 最后保存得到
previewImage图片。
注意
:你可以在Android emulator的Application中,直接看到"Widget Preview"的这个
APK
应用程序,它的源码位于
android-sdk-windows\samples\android-12\WidgetPreview目录下
二,App Widgets中collection views简介
App Widget通过RemoteViewsService提供的RemoteViewsFactory来进行数据集的显示。用于数据集显示的View,我们将称其为“集合视图"或“collection views”,它可以为以下类型之一:
ListView
该类view将以垂直可滚动列表的形式进行数据集中所有数据项的显示。最具代表性的是Gmail app widget
GridView
该view将以水平和垂直都可以滚动的grid(网格状)形式进行数据集中所有数据项的显示。最具代表性的是Bookmarks app widget
StackView
A stacked card view (kind of like a rolodex), 你可以对最前面一张card进行上翻(flick)/下翻(flick)来看到前一张/后一张 card,。最具代表性的是 YouTube and Books app widgets.
AdapterViewFlipper
An adapter-backed simple ViewAnimator that animates between two or more views. Only one child is shown at a time.
如上所述,这些collection views将显示由远程数据所组成的数据集合.这就意味着我们需要一个Adapter来把数据绑定到视图。
这个Adapter要负责把数据集的单个数据项和单个View对象进行绑定.
因为collection views是由adapters在后台提供的, 所以Android framework必须使用另外一种框架来支持在app widgets中使用它们.
在app widget应用中, 我们使用RemoteViewsFactory来代替Adapter , RemoteViewsFactory提供了和Adapter类似的接口.当请求数据集的一个数据项的时候,RemoteViewsFactory将以一个RemoteViews的形式返回数据集的一个数据项.为了在app widget中能使用collection view, 你必须实现一个RemoteViewsService和RemoteViewsFactory
RemoteViewsService是一个service,远程的adapter可以通过它请求并获得RemoteViews对象.
RemoteViewsFactory
为collection view (such as
ListView
,
GridView
, and so on)和collection view的数据提供了适配接口。
这里是实现RemoteViewsService和其接口的一个代码样板:
示例2
public class StackWidgetService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return new StackRemoteViewsFactory(this.getApplicationContext(), intent); } } class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { //... include adapter-like methods here. See the StackView Widget sample. }
例子程序
以下是StackView Widget示例程序的一个界面截图
![Widgets高级篇(上) - hubingforever - 民主与科学](http://developer.android.com/resources/samples/images/StackWidget.png)
This sample consists of a stack of 10 views, which display the values "0!" through "9!" The sample app widget has these primary behaviors:
首先、The user can vertically fling the top view in the app widget to display the next or previous view. This is a built-in StackView behavior.
其次
、
Without any user interaction, the app widget automatically advances through its views in sequence, like a slide show. This is due to the setting
android:autoAdvanceViewId="@id/stack_view"
in the
res/xml/stackwidgetinfo.xml
file. This setting applies to the view ID, which in this case is the view ID of the stack view.
最后、If the user touches the top view, the app widget displays the Toast message "Touched view n," where n is the index (position) of the touched view. For more discussion of how this is implemented, see Adding behavior to individual items。
关于StackView Widget示例程序的相信内容请阅读《
StackView Widget示例程序》
三、Implementing app widgets with collections
To implement an App Widget with collections, you follow the same basic steps you would use to implement any app widget. The following sections describe the additional steps you need to perform to implement an App Widget with collections.
3.1、Manifest for app widgets with collections
In addition to the requirements listed in Declaring an App Widget in the Manifest, to make it possible for App Widgets with collections to bind to your RemoteViewsService, you must declare the service in your manifest file with the permission BIND_REMOTEVIEWS. This prevents other applications from freely accessing your app widget's data. For example, when creating an App Widget that uses RemoteViewsService to populate a collection view, the manifest entry may look like this:
<service android:name="MyWidgetService" ... android:permission="android.permission.BIND_REMOTEVIEWS" />
这里的android:name="MyWidgetService" 是就你的RemoteViewsService.
3.2、Layout for app widgets with collections
你的app widget的布局文件应该包括下面之一的 collection views: ListView, GridView, StackView, or AdapterViewFlipper.
下面就是StackView Widget示例程序的布局文件widget_layout.xml
:
示例3
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <StackView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/stack_view" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:loopViews="true" /> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/empty_view" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:background="@drawable/widget_item_background" android:textColor="#ffffff" android:textStyle="bold" android:text="@string/empty_view_text" android:textSize="20sp" /> </FrameLayout>
注意
:empty views是在collection view为空(数据集为空)的时候,显示的view.关于次的更多内容,你将在后文看到。
除了这个布局文件,你改要编写另外的布局文件,以用于数据项的View布局。比如,在
StackView Widget示例程序中它只有一个用于数据项显示的View布局的文件, widget_item.xml。而在WeatherList Widget示例程序中,它只有两个用于数据项显示的View布局的文件: dark_widget_item.xml和light_widget_item.xml