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 b2a13427847..00000000000
Binary files a/samples/HoneycombGallery/res/drawable-nodpi/widget_preview.png and /dev/null differ
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.
+
+
+
\ 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 00000000000..8074c4c571b
Binary files /dev/null and b/samples/StackWidget/res/drawable-hdpi/icon.png differ
diff --git a/samples/StackWidget/res/drawable-ldpi/icon.png b/samples/StackWidget/res/drawable-ldpi/icon.png
new file mode 100644
index 00000000000..1095584ec21
Binary files /dev/null and b/samples/StackWidget/res/drawable-ldpi/icon.png differ
diff --git a/samples/StackWidget/res/drawable-mdpi/icon.png b/samples/StackWidget/res/drawable-mdpi/icon.png
new file mode 100644
index 00000000000..a07c69fa5a0
Binary files /dev/null and b/samples/StackWidget/res/drawable-mdpi/icon.png differ
diff --git a/samples/StackWidget/res/drawable-nodpi/preview.png b/samples/StackWidget/res/drawable-nodpi/preview.png
new file mode 100644
index 00000000000..f2f83a0adcb
Binary files /dev/null and b/samples/StackWidget/res/drawable-nodpi/preview.png differ
diff --git a/samples/StackWidget/res/drawable-nodpi/widget_item_background.xml b/samples/StackWidget/res/drawable-nodpi/widget_item_background.xml
new file mode 100644
index 00000000000..c0b3843e8c4
--- /dev/null
+++ b/samples/StackWidget/res/drawable-nodpi/widget_item_background.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
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;