From 1ff28c7b12986856d8a975d4713d35093b831016 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Thu, 10 Feb 2011 18:19:50 -0800 Subject: [PATCH] Making StackWidget sample code stand alone as opposed to bundled with HoneycombGallery Change-Id: I9da8433ee8a9710f5a5362a6f82fc96d4f456c88 --- samples/HoneycombGallery/AndroidManifest.xml | 14 -- samples/HoneycombGallery/_index.html | 4 +- .../res/drawable-nodpi/widget_preview.png | Bin 2515 -> 0 bytes .../res/drawable/widget_item_background.xml | 19 --- .../res/layout/widget_item.xml | 25 ---- .../HoneycombGallery/res/xml/widget_info.xml | 23 --- .../hcgallery/widget/WidgetService.java | 136 ------------------ samples/StackWidget/Android.mk | 16 +++ samples/StackWidget/AndroidManifest.xml | 39 +++++ samples/StackWidget/_index.html | 31 ++++ .../StackWidget/res/drawable-hdpi/icon.png | Bin 0 -> 4147 bytes .../StackWidget/res/drawable-ldpi/icon.png | Bin 0 -> 1723 bytes .../StackWidget/res/drawable-mdpi/icon.png | Bin 0 -> 2574 bytes .../res/drawable-nodpi/preview.png | Bin 0 -> 2525 bytes .../drawable-nodpi/widget_item_background.xml | 18 +++ .../StackWidget/res/layout/widget_item.xml | 24 ++++ .../res/layout/widget_layout.xml | 25 ++-- samples/StackWidget/res/values/strings.xml | 18 +++ .../StackWidget/res/xml/stackwidgetinfo.xml | 24 ++++ .../stackwidget/StackWidgetProvider.java} | 24 ++-- .../stackwidget/StackWidgetService.java | 133 +++++++++++++++++ .../android/stackwidget}/WidgetItem.java | 2 +- 22 files changed, 329 insertions(+), 246 deletions(-) delete mode 100644 samples/HoneycombGallery/res/drawable-nodpi/widget_preview.png delete mode 100644 samples/HoneycombGallery/res/drawable/widget_item_background.xml delete mode 100644 samples/HoneycombGallery/res/layout/widget_item.xml delete mode 100644 samples/HoneycombGallery/res/xml/widget_info.xml delete mode 100644 samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetService.java create mode 100644 samples/StackWidget/Android.mk create mode 100644 samples/StackWidget/AndroidManifest.xml create mode 100644 samples/StackWidget/_index.html create mode 100644 samples/StackWidget/res/drawable-hdpi/icon.png create mode 100644 samples/StackWidget/res/drawable-ldpi/icon.png create mode 100644 samples/StackWidget/res/drawable-mdpi/icon.png create mode 100644 samples/StackWidget/res/drawable-nodpi/preview.png create mode 100644 samples/StackWidget/res/drawable-nodpi/widget_item_background.xml create mode 100644 samples/StackWidget/res/layout/widget_item.xml rename samples/{HoneycombGallery => StackWidget}/res/layout/widget_layout.xml (56%) create mode 100644 samples/StackWidget/res/values/strings.xml create mode 100644 samples/StackWidget/res/xml/stackwidgetinfo.xml rename samples/{HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetProvider.java => StackWidget/src/com/example/android/stackwidget/StackWidgetProvider.java} (83%) create mode 100644 samples/StackWidget/src/com/example/android/stackwidget/StackWidgetService.java rename samples/{HoneycombGallery/src/com/example/android/hcgallery/widget => StackWidget/src/com/example/android/stackwidget}/WidgetItem.java (94%) diff --git a/samples/HoneycombGallery/AndroidManifest.xml b/samples/HoneycombGallery/AndroidManifest.xml index 60fd4c62fc1..6e6163bf0e0 100644 --- a/samples/HoneycombGallery/AndroidManifest.xml +++ b/samples/HoneycombGallery/AndroidManifest.xml @@ -47,19 +47,5 @@ - - - - - - - - - - diff --git a/samples/HoneycombGallery/_index.html b/samples/HoneycombGallery/_index.html index 963661e988e..5566fb5d29d 100644 --- a/samples/HoneycombGallery/_index.html +++ b/samples/HoneycombGallery/_index.html @@ -9,8 +9,8 @@
  • The new android.animation framework
  • Custom notifications
  • -
  • StackView - and other adapter-based app widgets
  • +
  • For information on how to implement StackView + and other adapter-based app widgets, see StackView App Widget
  • The image gallery shows how all these pieces can work together in one application.

    diff --git a/samples/HoneycombGallery/res/drawable-nodpi/widget_preview.png b/samples/HoneycombGallery/res/drawable-nodpi/widget_preview.png deleted file mode 100644 index b2a13427847666d10c052e68a336c40ba7bc3ce0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2515 zcmaJ@X;c$g7LFK@Fhos&V;Z$hheZV;m9QoxtRVzLXf}mbk%Uk{ge)cj!sbZQ9peD) z3JT)ZxU^^s?Vuo=R4ZrN(;%ogARvg2(lfHE1Z15m5W9bjQ|G*T_3pdhcfa@Ety^_4 zBsc(TVrhaxp|F7*Rv6rO!mY;G2);M3)6~J;7fSyqWw-k}ydlwRcEF zQ5=&L>B0keGCwd;#L19@;TgdZ!i*##Eso^nNo1(#Fo76U3WzFkvP3~wF-Z%&bod!D zlS#w{7iAKYv?wZy7ee%t%0Z%wBj6weTmhmh#gXFV?B?dSg-8V`02!c?DO3lF8{LUY z2LR&7iv&lL$HmjbSnQ9n;1QFQs8q`6WO7N>h|f60CG_31ZnNT8ZN0Ho+T4RtaQeiX(t5X~~ht z`~R+D@h5MEG7S7f@BbuLM5N0=au}$PrpSfx!Npr4p=5MFIVey{*^LX??i9#um2*E%WlLRw3ibQdAe|Hyue=5tD;_K>9q4)zd zUsswB&DGb}$K4sA0sc!^mQ&(T6P!KBgrt0$D1C88^#E3TJ&G9Kf2u0T7!rfq=`0ZQkm@ z1)DViZ))Ay*A#yGtvDrRo5p8%z^LsC@BQZ?Z#4~d4w4x>;p6idqnR)ZpQS{3Yx>b; z5P~Z4b~%YIm27#eK`*!ZVL8gubYlqC7W&mNcO4OSc*G-~~WBx1i z67kK;yfs|Fyc(@Qweb(@$Ef@o#CWo~?{9Mv8!=jgR)zYukuTz=a$VcJtP#UjA9-kCKcm|O$<#;q zn?{puPvS$K>-%&%gA@EsGHXIGfX~Y^KM7`Fv}So|znlarbbP--)jXR8tMkjTTExj< z?y7mbDfT+7FFgpbB3bTIpKtv8Q~pX6%wTHh2;22B>hq8b!Gy5}6ThhSlZf+;u-u+G zF5p~k~G9j{@3?TeGS=b zwOZ}m>_mZmeDN-9k-8UEQu*P+q$wqY87YqGGk@zL}`;Y5nlCwfd31v(-amFaNP~ zZuY~w1Pq&EmaJ4(UYdATz1Qkz$TNG&+}76imboB{r+#%Aa*z*Jlm;Bq-aW8tqvTXk z5hkV~>*?FB>4^~=!ga_lWp3s}TU%Sj(D(+gec#rmjY#YpRapH{cU4<^y4x=>JHVR#j?={#Z;u+=N@3?m)CyFO!^epZzG#Vbi^*mHAR z=*0{6qeofqr^$sj1pGCVO#L8+$z&ev-d(4{UAlaE{+-h!{1#UNzOoIQI`*Qet*fiJ zdgx(kfJHXDYg5!Pn{OEW75iRqZ*Tjhz#2tqu~F{CX1gft?oPBvrat-i!NH&&R}YV! zQ;&~ty^yafXo$%<_8a=m$jH|YH?}^uAKGExTRS=Y%)_D-$}QrLeg8oqUfB$P(lcG_aX%9qVRr6c zEJcNdg$&PAvAZ-)YcpPsM;@)-Ls;Xs2e-jy^mWUr_9JE;`@bXL$k8?CUESSgRV^(o z1?+n}?p>UG(@}olYGk=~czE~`H9Jciu+B}|TUT`7p!{-%*OM!~mQ&Ny(KiR8>gP=| zhc}&MLRp4*Q!A2--BkGLJRK22A!XT`a1LtJ86$Q2qs5uPXQ7d)!|=-wPa)+x cgy3aJKxs4`(mR|FMC3Os&_9@U-IuTaFR!l(ga7~l diff --git a/samples/HoneycombGallery/res/drawable/widget_item_background.xml b/samples/HoneycombGallery/res/drawable/widget_item_background.xml deleted file mode 100644 index aad4da35e2b..00000000000 --- a/samples/HoneycombGallery/res/drawable/widget_item_background.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/samples/HoneycombGallery/res/layout/widget_item.xml b/samples/HoneycombGallery/res/layout/widget_item.xml deleted file mode 100644 index a1cbe1f83c5..00000000000 --- a/samples/HoneycombGallery/res/layout/widget_item.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/samples/HoneycombGallery/res/xml/widget_info.xml b/samples/HoneycombGallery/res/xml/widget_info.xml deleted file mode 100644 index db95f9c31df..00000000000 --- a/samples/HoneycombGallery/res/xml/widget_info.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetService.java b/samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetService.java deleted file mode 100644 index e7aaa6b3726..00000000000 --- a/samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetService.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example.android.hcgallery.widget; - -import com.example.android.hcgallery.R; - -import java.util.ArrayList; -import java.util.List; -import android.appwidget.AppWidgetManager; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.widget.RemoteViews; -import android.widget.RemoteViewsService; - -public class WidgetService extends RemoteViewsService { - - private class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { - private static final int mCount = 10; - private List mWidgetItems = new ArrayList(); - private Context mContext; - private int mAppWidgetId; - - public StackRemoteViewsFactory(Context context, Intent intent) { - mContext = context; - mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, - AppWidgetManager.INVALID_APPWIDGET_ID); - } - - public void onCreate() { - // In onCreate() you setup any connections / cursors to your data source. Heavy lifting, - // for example downloading or creating content etc, should be deferred to getViewAt() or - // onDataSetChanged(). Taking more than 20 seconds in this call will result in an ANR. - for (int i = 0; i < mCount; i++) { - mWidgetItems.add(new WidgetItem(i + "!")); - } - - // We sleep for 3 seconds here to show how the empty view appears in the interim. - // The empty view is set in the WidgetProvider and should be a sibling of the - // collection view. - try { - Thread.sleep(3000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - public void onDestroy() { - // In onDestroy() you should tear down anything that was setup for your data source, - // eg. cursors, connections, etc. - mWidgetItems.clear(); - } - - public int getCount() { - return mCount; - } - - public RemoteViews getViewAt(int position) { - // position will always range from 0 to getCount() - 1. - - // We construct a remote views item based on our widget item xml file, and set the - // text based on the position. - RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item); - rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text); - - // Next, we set an intent so that clicking on this view will result in a toast message - Bundle extras = new Bundle(); - extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); - extras.putInt("numberToToast", position); - Intent fillInIntent = new Intent(); - fillInIntent.putExtras(extras); - rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); - - // You can do heaving lifting in here, synchronously. For example, if you need to - // process an image, fetch something from the network, etc., it is ok to do it here, - // synchronously. A loading view will show up in lieu of the actual contents in the - // interim. - try { - Log.d("WidgetService/getViewAt", "Loading view " + position); - // Simulating a time-consuming operation. NO NEED to include this call in your app! - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - // Return our remote views object. - return rv; - } - - public RemoteViews getLoadingView() { - // You can create a custom loading view (for instance when getViewAt() is slow. If you - // return null here, you will get the default loading view. - return null; - } - - public int getViewTypeCount() { - return 1; - } - - public long getItemId(int position) { - return position; - } - - public boolean hasStableIds() { - return true; - } - - public void onDataSetChanged() { - // This is triggered when you call AppWidgetManager notifyAppWidgetViewDataChanged - // on the collection view corresponding to this factory. You can do heaving lifting in - // here, synchronously. For example, if you need to process an image, fetch something - // from the network, etc., it is ok to do it here, synchronously. The widget will remain - // in its current state while work is being done here, so you don't need to worry about - // locking up the widget. - } - } - - public RemoteViewsFactory onGetViewFactory(Intent intent) { - return new StackRemoteViewsFactory(this.getApplicationContext(), intent); - } -} diff --git a/samples/StackWidget/Android.mk b/samples/StackWidget/Android.mk new file mode 100644 index 00000000000..016a454eafb --- /dev/null +++ b/samples/StackWidget/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +# Only compile source java files in this apk. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := StackWidget + +LOCAL_SDK_VERSION := current + +include $(BUILD_PACKAGE) + +# Use the following include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/samples/StackWidget/AndroidManifest.xml b/samples/StackWidget/AndroidManifest.xml new file mode 100644 index 00000000000..1fec1570e6c --- /dev/null +++ b/samples/StackWidget/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/StackWidget/_index.html b/samples/StackWidget/_index.html new file mode 100644 index 00000000000..e1af3179a3a --- /dev/null +++ b/samples/StackWidget/_index.html @@ -0,0 +1,31 @@ +

    + This sample shows how to construct a simple collection widget. This particular example shows how + to create a widget containing a StackView + ; however, only minimal changes are required to include + a ListView, + GridView or + AdapterViewFlipper instead. +

    +

    + The sample demonstrates the following: +

    +
      +
    • + The pattern for creating and wiring a RemoteViewsService + and RemoteViewsFactory which + serve the function of an adapter for the widget collection. +
    • +
    • + The pattern for setting an intent template and fill-in intents in order to + provide children of the collection with click behaviour. +
    • +
    • + How to make a widget with a StackView + (or AdapterViewFlipper) auto-advance. +
    • +
    • + How to set a widget preview image. +
    • +
    +The widget. \ No newline at end of file diff --git a/samples/StackWidget/res/drawable-hdpi/icon.png b/samples/StackWidget/res/drawable-hdpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8074c4c571b8cd19e27f4ee5545df367420686d7 GIT binary patch literal 4147 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 literal 0 HcmV?d00001 diff --git a/samples/StackWidget/res/drawable-ldpi/icon.png b/samples/StackWidget/res/drawable-ldpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1095584ec21f71cd0afc9e0993aa2209671b590c GIT binary patch literal 1723 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 + + + + diff --git a/samples/StackWidget/res/layout/widget_item.xml b/samples/StackWidget/res/layout/widget_item.xml new file mode 100644 index 00000000000..75e31ab51f0 --- /dev/null +++ b/samples/StackWidget/res/layout/widget_item.xml @@ -0,0 +1,24 @@ + + + diff --git a/samples/HoneycombGallery/res/layout/widget_layout.xml b/samples/StackWidget/res/layout/widget_layout.xml similarity index 56% rename from samples/HoneycombGallery/res/layout/widget_layout.xml rename to samples/StackWidget/res/layout/widget_layout.xml index 987465086fe..11f9d3665ef 100644 --- a/samples/HoneycombGallery/res/layout/widget_layout.xml +++ b/samples/StackWidget/res/layout/widget_layout.xml @@ -1,19 +1,18 @@ - + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> @@ -31,6 +30,6 @@ android:background="@drawable/widget_item_background" android:textColor="#ffffff" android:textStyle="bold" - android:text="@string/widget_empty_view_text" + android:text="@string/empty_view_text" android:textSize="20sp" /> diff --git a/samples/StackWidget/res/values/strings.xml b/samples/StackWidget/res/values/strings.xml new file mode 100644 index 00000000000..acb2f7feee7 --- /dev/null +++ b/samples/StackWidget/res/values/strings.xml @@ -0,0 +1,18 @@ + + + + This is the empty view + diff --git a/samples/StackWidget/res/xml/stackwidgetinfo.xml b/samples/StackWidget/res/xml/stackwidgetinfo.xml new file mode 100644 index 00000000000..8c2630f5389 --- /dev/null +++ b/samples/StackWidget/res/xml/stackwidgetinfo.xml @@ -0,0 +1,24 @@ + + + + \ No newline at end of file diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetProvider.java b/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetProvider.java similarity index 83% rename from samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetProvider.java rename to samples/StackWidget/src/com/example/android/stackwidget/StackWidgetProvider.java index 07a984d14a9..e053c210334 100644 --- a/samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetProvider.java +++ b/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,9 +14,7 @@ * limitations under the License. */ -package com.example.android.hcgallery.widget; - -import com.example.android.hcgallery.R; +package com.example.android.stackwidget; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; @@ -27,8 +25,9 @@ import android.widget.RemoteViews; import android.widget.Toast; -public class WidgetProvider extends AppWidgetProvider { - public static String TOAST_ACTION = "com.example.android.widget.action.TOAST"; +public class StackWidgetProvider extends AppWidgetProvider { + public static final String TOAST_ACTION = "com.example.android.stackwidget.TOAST_ACTION"; + public static final String EXTRA_ITEM = "com.example.android.stackwidget.EXTRA_ITEM"; @Override public void onDeleted(Context context, int[] appWidgetIds) { @@ -47,12 +46,11 @@ public void onEnabled(Context context) { @Override public void onReceive(Context context, Intent intent) { - AppWidgetManager mgr = AppWidgetManager.getInstance(context); if (intent.getAction().equals(TOAST_ACTION)) { int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); - int viewIndex = intent.getIntExtra("numberToToast", 0); + int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0); Toast.makeText(context, "Touched view " + viewIndex, Toast.LENGTH_SHORT).show(); } super.onReceive(context, intent); @@ -65,7 +63,7 @@ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] a // Here we setup the intent which points to the StackViewService which will // provide the views for this collection. - Intent intent = new Intent(context, WidgetService.class); + Intent intent = new Intent(context, StackWidgetService.class); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); // When intents are compared, the extras are ignored, so we need to embed the extras // into the data so that the extras will not be ignored. @@ -81,10 +79,10 @@ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] a // cannot setup their own pending intents, instead, the collection as a whole can // setup a pending intent template, and the individual items can set a fillInIntent // to create unique before on an item to item basis. - Intent toastIntent = new Intent(context, WidgetProvider.class); - toastIntent.setAction(WidgetProvider.TOAST_ACTION); + Intent toastIntent = new Intent(context, StackWidgetProvider.class); + toastIntent.setAction(StackWidgetProvider.TOAST_ACTION); toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); - toastIntent.setData(Uri.parse("widgetid" + appWidgetIds[i])); + intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent, PendingIntent.FLAG_UPDATE_CURRENT); rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent); @@ -93,4 +91,4 @@ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] a } super.onUpdate(context, appWidgetManager, appWidgetIds); } -} +} \ No newline at end of file diff --git a/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetService.java b/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetService.java new file mode 100644 index 00000000000..d53b0ea5d1e --- /dev/null +++ b/samples/StackWidget/src/com/example/android/stackwidget/StackWidgetService.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.android.stackwidget; + +import java.util.ArrayList; +import java.util.List; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +public class StackWidgetService extends RemoteViewsService { + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + return new StackRemoteViewsFactory(this.getApplicationContext(), intent); + } +} + +class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { + private static final int mCount = 10; + private List mWidgetItems = new ArrayList(); + private Context mContext; + private int mAppWidgetId; + + public StackRemoteViewsFactory(Context context, Intent intent) { + mContext = context; + mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + } + + public void onCreate() { + // In onCreate() you setup any connections / cursors to your data source. Heavy lifting, + // for example downloading or creating content etc, should be deferred to onDataSetChanged() + // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR. + for (int i = 0; i < mCount; i++) { + mWidgetItems.add(new WidgetItem(i + "!")); + } + + // We sleep for 3 seconds here to show how the empty view appears in the interim. + // The empty view is set in the StackWidgetProvider and should be a sibling of the + // collection view. + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void onDestroy() { + // In onDestroy() you should tear down anything that was setup for your data source, + // eg. cursors, connections, etc. + mWidgetItems.clear(); + } + + public int getCount() { + return mCount; + } + + public RemoteViews getViewAt(int position) { + // position will always range from 0 to getCount() - 1. + + // We construct a remote views item based on our widget item xml file, and set the + // text based on the position. + RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item); + rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text); + + // Next, we set a fill-intent which will be used to fill-in the pending intent template + // which is set on the collection view in StackWidgetProvider. + Bundle extras = new Bundle(); + extras.putInt(StackWidgetProvider.EXTRA_ITEM, position); + Intent fillInIntent = new Intent(); + fillInIntent.putExtras(extras); + rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); + + // You can do heaving lifting in here, synchronously. For example, if you need to + // process an image, fetch something from the network, etc., it is ok to do it here, + // synchronously. A loading view will show up in lieu of the actual contents in the + // interim. + try { + System.out.println("Loading view " + position); + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + // Return the remote views object. + return rv; + } + + public RemoteViews getLoadingView() { + // You can create a custom loading view (for instance when getViewAt() is slow.) If you + // return null here, you will get the default loading view. + return null; + } + + public int getViewTypeCount() { + return 1; + } + + public long getItemId(int position) { + return position; + } + + public boolean hasStableIds() { + return true; + } + + public void onDataSetChanged() { + // This is triggered when you call AppWidgetManager notifyAppWidgetViewDataChanged + // on the collection view corresponding to this factory. You can do heaving lifting in + // here, synchronously. For example, if you need to process an image, fetch something + // from the network, etc., it is ok to do it here, synchronously. The widget will remain + // in its current state while work is being done here, so you don't need to worry about + // locking up the widget. + } +} \ No newline at end of file diff --git a/samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetItem.java b/samples/StackWidget/src/com/example/android/stackwidget/WidgetItem.java similarity index 94% rename from samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetItem.java rename to samples/StackWidget/src/com/example/android/stackwidget/WidgetItem.java index 4c4b230d1e4..aa822ca3309 100644 --- a/samples/HoneycombGallery/src/com/example/android/hcgallery/widget/WidgetItem.java +++ b/samples/StackWidget/src/com/example/android/stackwidget/WidgetItem.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.android.hcgallery.widget; +package com.example.android.stackwidget; public class WidgetItem { public String text;