diff options
| author | Adam Cohen <adamcohen@google.com> | 2010-10-26 10:35:01 -0700 |
|---|---|---|
| committer | Adam Cohen <adamcohen@google.com> | 2010-11-01 20:53:38 -0700 |
| commit | a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20 (patch) | |
| tree | 21629b5d915eadcbfeb68218c11df716b4363980 /core/java/android/widget/RemoteViews.java | |
| parent | 2444ddb3d9b59ec45ba50858fcbff639e59b93b1 (diff) | |
Adding click feedback to widget collections
Change-Id: I97fceb6c68ca6eb1b703eafacf201e1aed7c38e7
Diffstat (limited to 'core/java/android/widget/RemoteViews.java')
| -rw-r--r-- | core/java/android/widget/RemoteViews.java | 153 |
1 files changed, 52 insertions, 101 deletions
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 6ba7b44fe1eb..24165aa7f344 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -45,6 +45,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.LayoutInflater.Filter; import android.view.View.OnClickListener; +import android.widget.AdapterView.OnItemClickListener; /** @@ -110,7 +111,7 @@ public class RemoteViews implements Parcelable, Filter { super(message); } } - + /** * Base class for all actions that can be performed on an * inflated view. @@ -216,8 +217,9 @@ public class RemoteViews implements Parcelable, Filter { "only from RemoteViewsFactory (ie. on collection items)."); return; } - - if (target != null && fillInIntent != null) { + if (target == root) { + target.setTagInternal(com.android.internal.R.id.fillInIntent, fillInIntent); + } else if (target != null && fillInIntent != null) { OnClickListener listener = new OnClickListener() { public void onClick(View v) { // Insure that this view is a child of an AdapterView @@ -237,14 +239,14 @@ public class RemoteViews implements Parcelable, Filter { // Insure that a template pending intent has been set on an ancestor if (!(parent.getTag() instanceof PendingIntent)) { Log.e("RemoteViews", "Attempting setOnClickFillInIntent without" + - " calling setPendingIntentTemplate on parent."); + " calling setPendingIntentTemplate on parent."); return; } PendingIntent pendingIntent = (PendingIntent) parent.getTag(); final float appScale = v.getContext().getResources() - .getCompatibilityInfo().applicationScale; + .getCompatibilityInfo().applicationScale; final int[] pos = new int[2]; v.getLocationOnScreen(pos); @@ -269,88 +271,6 @@ public class RemoteViews implements Parcelable, Filter { public final static int TAG = 9; } - private class SetOnClickExtras extends Action { - public SetOnClickExtras(int id, Bundle extras) { - this.viewId = id; - this.extras = extras; - } - - public SetOnClickExtras(Parcel parcel) { - viewId = parcel.readInt(); - extras = Bundle.CREATOR.createFromParcel(parcel); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - extras.writeToParcel(dest, 0 /* no flags */); - } - - @Override - public void apply(View root) { - final View target = root.findViewById(viewId); - if (target == null) return; - - if (!mIsWidgetCollectionChild) { - Log.e("RemoteViews", "The method setOnClickExtras is available " + - "only from RemoteViewsFactory (ie. on collection items)."); - return; - } - - if (target != null && extras != null) { - OnClickListener listener = new OnClickListener() { - public void onClick(View v) { - // Insure that this view is a child of an AdapterView - View parent = (View) v.getParent(); - while (!(parent instanceof AdapterView<?>) - && !(parent instanceof AppWidgetHostView)) { - parent = (View) parent.getParent(); - } - - if (parent instanceof AppWidgetHostView) { - // Somehow they've managed to get this far without having - // and AdapterView as a parent. - Log.e("RemoteViews", "Collection item doesn't have AdapterView parent"); - return; - } - - // Insure that a template pending intent has been set on an ancestor - if (!(parent.getTag() instanceof PendingIntent)) { - Log.e("RemoteViews", "Attempting setOnClickExtras without calling " + - "setPendingIntentTemplate on parent."); - return; - } - - PendingIntent pendingIntent = (PendingIntent) parent.getTag(); - - final float appScale = v.getContext().getResources() - .getCompatibilityInfo().applicationScale; - final int[] pos = new int[2]; - v.getLocationOnScreen(pos); - - final Rect rect = new Rect(); - rect.left = (int) (pos[0] * appScale + 0.5f); - rect.top = (int) (pos[1] * appScale + 0.5f); - rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f); - rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f); - - final Intent intent = new Intent(); - intent.setSourceBounds(rect); - intent.putExtras(extras); - startIntentSafely(v.getContext(), pendingIntent, intent); - } - - }; - target.setOnClickListener(listener); - } - } - - int viewId; - Bundle extras; - - public final static int TAG = 7; - } - private class SetPendingIntentTemplate extends Action { public SetPendingIntentTemplate(int id, PendingIntent pendingIntentTemplate) { this.viewId = id; @@ -375,8 +295,52 @@ public class RemoteViews implements Parcelable, Filter { // If the view isn't an AdapterView, setting a PendingIntent template doesn't make sense if (target instanceof AdapterView<?>) { + AdapterView<?> av = (AdapterView<?>) target; // The PendingIntent template is stored in the view's tag. - target.setTag(pendingIntentTemplate); + OnItemClickListener listener = new OnItemClickListener() { + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) { + // The view should be a frame layout + if (view instanceof ViewGroup) { + ViewGroup vg = (ViewGroup) view; + + // AdapterViews contain their children in a frame + // so we need to go one layer deeper here. + if (parent instanceof AdapterViewAnimator) { + vg = (ViewGroup) vg.getChildAt(0); + } + if (vg == null) return; + + Intent fillInIntent = null; + int childCount = vg.getChildCount(); + for (int i = 0; i < childCount; i++) { + Object tag = vg.getChildAt(i).getTag(com.android.internal.R.id.fillInIntent); + if (tag instanceof Intent) { + fillInIntent = (Intent) tag; + break; + } + } + if (fillInIntent == null) return; + + final float appScale = view.getContext().getResources() + .getCompatibilityInfo().applicationScale; + final int[] pos = new int[2]; + view.getLocationOnScreen(pos); + + final Rect rect = new Rect(); + rect.left = (int) (pos[0] * appScale + 0.5f); + rect.top = (int) (pos[1] * appScale + 0.5f); + rect.right = (int) ((pos[0] + view.getWidth()) * appScale + 0.5f); + rect.bottom = (int) ((pos[1] + view.getHeight()) * appScale + 0.5f); + + final Intent intent = new Intent(); + intent.setSourceBounds(rect); + startIntentSafely(view.getContext(), pendingIntentTemplate, fillInIntent); + } + } + }; + av.setOnItemClickListener(listener); + av.setTag(pendingIntentTemplate); } else { Log.e("RemoteViews", "Cannot setPendingIntentTemplate on a view which is not" + "an AdapterView (id: " + viewId + ")"); @@ -973,9 +937,6 @@ public class RemoteViews implements Parcelable, Filter { case SetEmptyView.TAG: mActions.add(new SetEmptyView(parcel)); break; - case SetOnClickExtras.TAG: - mActions.add(new SetOnClickExtras(parcel)); - break; case SetPendingIntentTemplate.TAG: mActions.add(new SetPendingIntentTemplate(parcel)); break; @@ -1239,16 +1200,6 @@ public class RemoteViews implements Parcelable, Filter { } /** - * Being deprecated. See {@link RemoteViews#setOnClickFillInIntent(int, Intent)}. - * - * @param viewId - * @param extras - */ - public void setOnClickExtras(int viewId, Bundle extras) { - addAction(new SetOnClickExtras(viewId, extras)); - } - - /** * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very * costly to set PendingIntents on the individual items, and is hence not permitted. Instead * a single PendingIntent template can be set on the collection, see {@link |
