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,如果選擇該小部件,就會將其添加到手機桌面,運行結果如下所示: