AppWidget应用小部件详解(一)
App Widget就是一个能够嵌入到别的应用程序(比如说Home screen)的应用小部件,而我们android手机也自带了一些这样的小部件,通过如下的步骤就能将手机自带的应用小部件添加到手机桌面:
1、长按手机桌面没有应用快捷键的空白区域,就会出现如下的小窗口:
2、从窗口中选择 WIDGETS 的选项,接着也会出现一个手机所有应用小部件列表的窗口:
3、选择需要添加应用小部件,该应用小部件就会添加到手机桌面上。
知道了怎样将应用小部件添加到手机桌面之后,接下来开始讲如何创建自定义的App Widget,编写App Widget之前需要知道的一些概念信息:
1、AppWidgetProviderInfo对象:用来描述App Widget的元数据,比如App Widget的布局、更新频率等,这个类并不需要我们创建,只需定义一个xml文件,android系统会根据这个xml创建这个AppWidgetProviderInfo对象。
2、AppWidgetProvider的实现类:是基于Broadcast事件的类,通过定义一些基本的方法与App Widget进行交互;当App Widget更新、激活、失效、删除的时候都会通过广播的形式通知这个类。
3、View的布局:App Widget初始化的布局文件。
知道这些概念之后,接下来进行进行自定义数字时钟的App Widget创建(基于android系统2.2)
1、首先创建AppWidgetProviderInfo对象,即在res/xml目录下创建一个appwidget_provider_time.xml,其代码如下:
<!--
android:minWidth:App Widget的最小宽度
android:minHeight:App Widget的最小高度
android:updatePeriodMillis:App Widget的更新频率
android:initialLayout:App Widget的初始化界面
-->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="50dp"
android:minHeight="25dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/appwidget_provider_clock" />
2、接着创建App Widget的布局文件,用于显示App Widget,其文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="200dp"
android:layout_height="70dp"
android:background="@drawable/shape"
android:orientation="horizontal" >
<TextView
android:id="@+id/txt_time"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_margin="7dp"
android:layout_weight="2"
android:background="#FFFFFF"
android:gravity="center"
android:textColor="#000000"
android:textStyle="bold"
android:textSize="25sp" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1.5"
android:layout_marginTop="6dp"
android:layout_marginBottom="5dp"
android:layout_marginRight="3dp" >
<TextView
android:id="@+id/txt_week"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFFFFF"
android:layout_alignParentTop="true" />
<TextView
android:id="@+id/txt_day"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="25sp"
android:layout_centerInParent="true" />
<TextView
android:id="@+id/txt_month"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFFFFF"
android:layout_alignParentBottom="true" />
</RelativeLayout>
</LinearLayout>
3、然后创建AppWidgetProvider的实现类ClockAppWidgetProvider,用来接收App Widget发布的广播,根据广播进行相关的创建、更新App Widget等操作,其核心代码如下:
private Context context;
private AppWidgetManager appWidgetManager;
private Timer timer;
//月份
private String[] months = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
//星期
private String[] weeks = new String[]{"Monday", "Tuesday", "Wednesday ", "Thursday", "Friday", "Saturday", "Sunday"};
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
//创建定时器
timer = new Timer();
this.context = context;
this.appWidgetManager = appWidgetManager;
//进行周期性调度: 1s更新一次界面
timer.schedule(new TimerTask() {
@Override
public void run() {
//通知更新界面
handler.sendEmptyMessage(0x123);
}
}, 0, 1000);
}
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what == 0x123)
{
//构造RemoteViews对象
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_clock);
//构造显示时间日期
Calendar calendar = Calendar.getInstance(Locale.CHINA);
calendar.setTimeInMillis(System.currentTimeMillis());
//构造当期显示时间
StringBuffer currentTime = new StringBuffer("");
int temp = calendar.get(Calendar.HOUR_OF_DAY);
if(temp < 10)
{
currentTime.append("0").append(temp);
}
else
{
currentTime.append(temp);
}
temp = calendar.get(Calendar.MINUTE);
if(temp < 10)
{
currentTime.append(":").append("0").append(temp);
}
else
{
currentTime.append(":").append(temp);
}
temp = calendar.get(Calendar.SECOND);
if(temp < 10)
{
currentTime.append(":").append("0").append(temp);
}
else
{
currentTime.append(":").append(temp);
}
//设置显示当前时间
views.setTextViewText(R.id.txt_time, currentTime.toString());
//设置显示当前月份
views.setTextViewText(R.id.txt_month, months[calendar.get(Calendar.MONTH)]);
//设置显示当前星期
views.setTextViewText(R.id.txt_week, weeks[calendar.get(Calendar.WEEK_OF_MONTH)]);
//设置显示当前日期
views.setTextViewText(R.id.txt_day, String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));
//将当前的ClockAppWidgetProvider包装成ComponentName对象
ComponentName componentName = new ComponentName(context, ClockAppWidgetProvider.class);
//更新App Widget
appWidgetManager.updateAppWidget(componentName, views);
}
}
};
4、最后将ClockAppWidgetProvider类注册到AndroidManifest.xml配置文件中,其文件如下:
<!-- 注册ClockAppWidgetProvider广播接收器 -->
<receiver android:name=".ClockAppWidgetProvider">
<!-- 广播接收的action:当appwidget改变时 -->
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<!-- 设置元数据:将ClockAppWidgetProvider类和AppWidgetProviderInfo对象appwidget_provider_time关联起来 -->
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_provider_time"/>
</receiver>
5、通过以上几步,自定义
数字时钟的App Widget就创建成功了,根据之前如何将应用小部件添加到手机桌面的步骤,在
WIDGETS列表中就会找到我们自定义的这个数字时钟的App Widget,如果选择该小部件,就会将其添加到手机桌面,运行结果如下所示: