AppWidget 窗口小部件的开发思想和Demo
这篇文章讲一下android系统“窗口小部件”(也叫做,主屏幕部件)的开发过程。什么叫窗口小部件呢?
是指在主屏幕上显示的独立视图(不过填充了数据)。这些视图的数据内容由后台进程顶起更新。要用到RemoteViews来
显示部件,还要指派广播接收器更新这些RemoteViews. 既可以单独做个窗口小部件,也可在App中嵌入多个窗口小部件。
如<图一>就是人人网客户端带个一个小部件和Google play的小部件。
<图一>
接下来就以"生日提醒"的例子简述下小部件的开发思想。
一:首先需要声明一个appwidget-provider控件
在res→xml里定义一个文件AppWidgetProviderInfo.xml文件。
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="150dp" //宽(这个有讲究,文章最后有注释*) android:minHeight="120dp" //长 android:updatePeriodMillis="86400000" //更新频率 ms为单位 android:initialLayout="@layout/bday_widget" //布局文件 android:configure="com.carman.birthdayremind.ConfigureBDayWidgetActivity" > //配置活动(可选) </appwidget-provider>
android:initialLayout这个属性就是你所要显示的界面,根据自己的需求来设计。
二:AppWidgetProvider 类的实现
要实现窗口小部件的开发,必须继承AppWidgetProvider 的子类。实现定义基本方法以允许你编程来和App Widget连接,这基于广播 事件。通过它,当这个App Widget被更新,启用,禁用和删除的时候,你都将接收到广播通知。
如下:BDayWidgetProvider.class
public class BDayWidgetProvider extends AppWidgetProvider { @Override public void onDeleted(Context context, int[] appWidgetIds) { // TODO Auto-generated method stub //当App Widget的实例从宿主中删除时被调用。 } @Override public void onDisabled(Context context) { 当你的App Widget的最后一个实例被从宿主中删除时被调用。因为:譬如上图中的人人网小部件,你可添加N个实例。 } @Override public void onEnabled(Context context) { // 当一个App Widget实例第一次创建时被调用。 } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { //这个方法调用来间隔性的更新App Widget,间隔时间用AppWidgetProviderInfo 里的updatePeriodMillis属性定义(参见添加AppWidgetProviderInfo元数据)。}
@Override public void onReceive(Context context, Intent intent) { //这个接收到每个广播时都会被调用,而且在上面的回调函数之前。你通常不需要实现这个方法,因为缺省的AppWidgetProvider实现过滤所有Ap p Widget 广播并恰当的调用上述方法。 }
}
要实现复杂的需求,也不外乎就是扩展上述类中的这几个方法。这里只讲原理,故不多说哈。
三:在manifest中注册并添加广播。
<receiver android:name=".BDayWidgetProvider" >
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/AppWidgetProviderInfo" />
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
</receiver>
<intent-filter> 元素必须包括一个含有android:name属性的<action>元素。该元素指定AppWidgetProvider接受ACTION_APPWIDGET_UPDATE 广播。这是唯一你必须显式声明的广播。当需要的时候,AppWidgetManager 会自动发送所有其他App Widget广播给AppWidgetProvider。
*【注释】:小部件的长宽的定义规则
缺省的App Widgets所在窗口的桌面位置基于有确切高度和宽度的单元网格。如果App Widget的最小长宽和这些网格单元的
尺寸不匹配,那么这个App Widget将收缩到最接近的单元尺寸(参见App Widget Design Guidelines 以获取更多关于桌面单元尺寸的信息)
因为桌面布局方向(由此,单元的尺寸)可以变化,按照拇指规则,你应该假设最坏情况单元尺寸是74像素高和宽。不过,你必须
从最后的尺寸中减去2以把像素计算过程中产生的任何的整数舍入误差考虑在内。要找到像素密度无关的最小宽度和高度,使用这个公式:
(number of cells * 74) - 2
遵循这个公式,你应该使用72dp为每一个单元高度,294dp为四个单元宽度。
已经以上三步就可以制作一个最简单的小窗口部件了。原理与已清楚了哈,下面说说我自己的BirthdayRemind的功能:
BirthdayRemind可通过配置文件输入姓名和日期,用来算某人生日的倒计时。小窗口每日会更新,数字将减1,并且做了一个“Buy”链接,
可用来调用购买生日礼物的链接。运行截图如<图二>,感兴趣的朋友可下载下来玩玩。
BirthdayRemind源码地址:http://pan.baidu.com/share/link?shareid=23016&uk=1442961174
<图二>
可以转载,但请注明出处,谢谢!
作者:Carman 2012-08-13 15:27:10