Android widget桌面小部件與RemoteViewsService
阿新 • • 發佈:2019-02-07
概述
android
中桌面外掛主要依賴於AppWidget
框架。涉及類:
AppWidgetProvider
:BroadcastRecevier子類,用於接收更新,刪除通知AppWidgetProvderInfo
:AppWidget相關資訊(大小,更新頻率等),xml形式AppWidgetManger
:AppWidget管理類,用於向provider傳送訊息RemoteViews
:可以在其他程序中執行的類,用於向provider傳送通知。RemoteViewsService
: 是一個遠端的服務介面卡 可以請求RemoteViews,管理RemoteViews的服務.RemoteViewsFactory
實現步驟
- 宣告
AndroidManifest
- 定義初始化
xml
檔案 - 定義
widget
佈局Layout xml
檔案 - 繼承
AppWidgetProvider
,實現相關邏輯
AndroidManifest.xml:
<receiver android:name="ExampleAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
AppWidgetProvider
其本質是一個BroadcastReceiver
,其中,APPWIDGET_UPDATE
是必須的,用於接收broadcast
。
meta-data
聲明瞭AppWidgetProviderInfo
對應的資源xml
的位置,其中包括Widget
xml
佈局檔案、重新整理頻率、最小寬高
res/xml/example_appwidget_info
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:previewImage="@drawable/preview"
android:initialLayout="@layout/example_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigure"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen">
</appwidget-provider>
- minWidth & minHeight:定義了 Widget 的最小寬高
- updatePeriodMillis:定義了 Widget 的重新整理頻率
- initialLayout:Widget 的佈局 Layout 檔案
- previewImage:當用戶選擇新增 Widget 時的預覽圖片
- configure:新增Widget時彈出的Widget配置activity,沒有則不設定
- resizeMode:水平和垂直方向是否可以調整大小,horizontal,vertical,none,horizontal|vertical
- widgetCategory: Widget 可以顯示的位置, home_screen(桌面),keyguard(鎖屏,5.0以上)
更多詳細屬性可以參考 AppWidgetProviderInfo。
ExampleAppWidgetProvider:
public class ExampleAppWidgetProvider extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(context, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
Configuration Activity
<activity android:name=".ExampleAppWidgetConfigure">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
新增widget
時彈出的activity
,需要新增android.appwidget.action.APPWIDGET_CONFIGURE
過濾器。
注意事項:
- Activity 必須返回帶
EXTRA_APPWIDGET_ID
的 result。 - 宣告
Configuration Activity
後 onUpdate() 在 Widget 新增時不會被呼叫,Activity 需要呼叫AppWidgetManager.updateAppWidget()
完成 Widget 更新。
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.example_appwidget);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
集合檢視RemoteViewsService
上面的方式提供的方式是針對單個widget,如果我們的widget中包含ListView
,Gridview
等集合檢視的時候.我們就需要藉助一個類RemoteViewsService
,繼承RemoteViewsService
並複寫onGetViewFactory
返回RemoteViewsFactory
public class StackWidgetRemoteViewsService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {}
}