馬上加入Android 台灣中文網,立即免費下載應用遊戲。
您需要 登錄 才可以下載或查看,沒有帳號?註冊
x
如果想讓你的應用支持appwidget,需要注意的幾點:
1.必須調用AppWidgetHost的startListening方法來監聽appwidget的狀態變化,否則添加上去的appwidget不會更新的。
2.需要override一個onActivityResult方法,來接收添加appwidget和appwidget的配置activity的返回值。
3.啟動AppWidgetManager.ACTION_APPWIDGET_PICK這個Intent,必須要給列表中加上自己定義的一個選項,否則出錯。如本例中是用的Search。
下面是完整的教程:
首先是得定義一個承載appwidget的容器,系統的Launcher裡面 是用的CellLayout,實現的很不錯。我這裡就用一個簡單的自定義ViewGroup來搞定,它是以長按的坐標處為要添加的appwidget的起 始位置,簡單點說就是按到哪兒就添加到哪兒。- package chroya.demo.widget;
-
- import android.content.Context;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewGroup;
-
- /**
- * 承載widget的容器
- * @author chroya
- */
- public class WidgetLayout extends ViewGroup {
- //存放touch的坐標
- private int[] cellInfo = new int[2];
- private OnLongClickListener mLongClickListener;
-
- public WidgetLayout(Context context) {
- super(context);
- mLongClickListener = new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View v) {
-
- return false;
- }
- };
- }
-
- public void addInScreen(View child, int width, int height) {
- LayoutParams lp = new LayoutParams(width, height);
- lp.x = cellInfo[0];
- lp.y = cellInfo[1];
- child.setOnLongClickListener(mLongClickListener);
- addView(child, lp);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- LayoutParams lp;
- for(int index=0; index<getChildCount(); index++) {
- lp = (LayoutParams) getChildAt(index).getLayoutParams();
- getChildAt(index).measure(
- MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, lp.width),
- MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, lp.height));
- }
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- cellInfo[0] = (int)event.getX();
- cellInfo[1] = (int)event.getY();
- return super.dispatchTouchEvent(event);
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- LayoutParams lp;
- for(int index=0; index<getChildCount(); index++) {
- lp = (LayoutParams) getChildAt(index).getLayoutParams();
- getChildAt(index).layout(lp.x, lp.y, lp.x+lp.width, lp.y+lp.height);
- }
- }
-
- public static class LayoutParams extends ViewGroup.LayoutParams {
- int x;
- int y;
-
- public LayoutParams(int width, int height) {
- super(width, height);
- }
- }
- }
複製代碼 然後是重點了。還記得系統默認的桌面上,長按的時候出現的上下文菜單嗎?裡面 有好幾個選項,選擇widget之後,會彈出一個已經安裝的widget列表,選擇一個widget之後,就會添加到桌面。我們可以把第一步去掉,長按之 後,直接彈出已安裝的widget列表,這是一個activity,用AppWidgetManager.ACTION_APPWIDGET_PICK這 個Intent來啟動,必須帶上Extras,下面給出代碼中有,不詳敘。- package chroya.demo.widget;
-
- import static android.util.Log.d;
-
- import java.util.ArrayList;
-
- import android.app.Activity;
- import android.appwidget.AppWidgetHost;
- import android.appwidget.AppWidgetManager;
- import android.appwidget.AppWidgetProviderInfo;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnLongClickListener;
-
- /**
- * 添加appwidget
- * @author chroya
- *
- */
- public class Main extends Activity {
- private AppWidgetHost mAppWidgetHost;
- private AppWidgetManager mAppWidgetManager;
- private WidgetLayout layout;
-
- private static final int REQUEST_PICK_APPWIDGET = 1;
- private static final int REQUEST_CREATE_APPWIDGET = 2;
- private static final int APPWIDGET_HOST_ID = 0x100;
- private static final String EXTRA_CUSTOM_WIDGET = "custom_widget";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mAppWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
- mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID);
- //開始監聽widget的變化
- mAppWidgetHost.startListening();
-
- layout = new WidgetLayout(this);
- layout.setOnLongClickListener(new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View v) {
-
- addWidget();
- return false;
- }
- });
- setContentView(layout);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == RESULT_OK) {
- switch (requestCode) {
- case REQUEST_PICK_APPWIDGET:
- addAppWidget(data);
- break;
- case REQUEST_CREATE_APPWIDGET:
- completeAddAppWidget(data);
- break;
- }
- } else if (requestCode == REQUEST_PICK_APPWIDGET &&
- resultCode == RESULT_CANCELED && data != null) {
- // Clean up the appWidgetId if we canceled
- int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
- if (appWidgetId != -1) {
- mAppWidgetHost.deleteAppWidgetId(appWidgetId);
- }
- }
- }
-
- /**
- * 選中了某個widget之後,根據是否有配置來決定直接添加還是彈出配置activity
- * @param data
- */
- private void addAppWidget(Intent data) {
- int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-
- String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET);
- d("addAppWidget", "data:"+ customWidget);
- if ("search_widget".equals(customWidget)) {
- //這裡直接將search_widget刪掉了
- mAppWidgetHost.deleteAppWidgetId(appWidgetId);
- } else {
- AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
-
- d("addAppWidget", "configure:"+ appWidget.configure);
- if (appWidget.configure != null) {
- //有配置,彈出配置
- Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
- intent.setComponent(appWidget.configure);
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-
- startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
- } else {
- //沒有配置,直接添加
- onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
- }
- }
- }
-
- /**
- * 請求添加一個新的widget
- */
- private void addWidget() {
- int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
-
- Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
- pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
- // add the search widget
- ArrayList<AppWidgetProviderInfo> customInfo =
- new ArrayList<AppWidgetProviderInfo>();
- AppWidgetProviderInfo info = new AppWidgetProviderInfo();
- info.provider = new ComponentName(getPackageName(), "XXX.YYY");
- info.label = "Search";
- info.icon = R.drawable.ic_search_widget;
- customInfo.add(info);
- pickIntent.putParcelableArrayListExtra(
- AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
- ArrayList<Bundle> customExtras = new ArrayList<Bundle>();
- Bundle b = new Bundle();
- b.putString(EXTRA_CUSTOM_WIDGET, "search_widget");
- customExtras.add(b);
- pickIntent.putParcelableArrayListExtra(
- AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
- // start the pick activity
- startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
- }
-
- /**
- * 添加widget
- * @param data
- */
- private void completeAddAppWidget(Intent data) {
- Bundle extras = data.getExtras();
- int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-
- d("completeAddAppWidget", "dumping extras content="+extras.toString());
- d("completeAddAppWidget", "appWidgetId:"+ appWidgetId);
- AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
-
- View hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
-
- layout.addInScreen(hostView, appWidgetInfo.minWidth, appWidgetInfo.minHeight);
- }
- }
複製代碼 運行效果如下:
|