diff options
| author | Stevie Kideckel <kideckel@google.com> | 2021-06-07 14:46:52 +0000 |
|---|---|---|
| committer | Stevie Kideckel <kideckel@google.com> | 2021-06-07 14:46:52 +0000 |
| commit | bfbe46198cb2f718862fa870509ec7f16f8f6c46 (patch) | |
| tree | 40829e3f92593b040df236a7d3dfb71a14d8c5a5 /core/java/android/widget/RemoteViews.java | |
| parent | ebcaa39d6b87e25e2f87319943186ea006405af5 (diff) | |
Fix handling for onItemClick of fixed collection items
The onItemClick handling code assumed that the item would be nested at
least one layer deep due to the RemoteViewsAdapter adding a wrapper view
group.
Rather than add another case to that logic, I've refactored this to
traverse the view's children looking for a view with the tag. As the
tag is internal, there should only ever be one child with it and we'll
always want that one to handle the click.
Fix: 190353630
Test: locally
Test: atest RemoteViewsFixedCollectionAdapterTest
Change-Id: I22057f148d33482ad84fff592b9f7f554fa2bfad
Diffstat (limited to 'core/java/android/widget/RemoteViews.java')
| -rw-r--r-- | core/java/android/widget/RemoteViews.java | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 25c84ba9d440..73d56daab6fb 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -114,6 +114,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Method; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -812,29 +813,8 @@ public class RemoteViews implements Parcelable, Filter { AdapterView<?> av = (AdapterView<?>) target; // The PendingIntent template is stored in the view's tag. OnItemClickListener listener = (parent, view, position, 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; - - RemoteResponse response = null; - int childCount = vg.getChildCount(); - for (int i = 0; i < childCount; i++) { - Object tag = vg.getChildAt(i).getTag(R.id.fillInIntent); - if (tag instanceof RemoteResponse) { - response = (RemoteResponse) tag; - break; - } - } - if (response == null) return; - response.handleViewInteraction(view, handler); - } + RemoteResponse response = findRemoteResponseTag(view); + response.handleViewInteraction(view, handler); }; av.setOnItemClickListener(listener); av.setTag(pendingIntentTemplate); @@ -845,6 +825,28 @@ public class RemoteViews implements Parcelable, Filter { } } + @Nullable + private RemoteResponse findRemoteResponseTag(@Nullable View rootView) { + if (rootView == null) return null; + + ArrayDeque<View> viewsToCheck = new ArrayDeque<>(); + viewsToCheck.addLast(rootView); + + while (!viewsToCheck.isEmpty()) { + View view = viewsToCheck.removeFirst(); + Object tag = view.getTag(R.id.fillInIntent); + if (tag instanceof RemoteResponse) return (RemoteResponse) tag; + if (!(view instanceof ViewGroup)) continue; + + ViewGroup viewGroup = (ViewGroup) view; + for (int i = 0; i < viewGroup.getChildCount(); i++) { + viewsToCheck.addLast(viewGroup.getChildAt(i)); + } + } + + return null; + } + @Override public int getActionTag() { return SET_PENDING_INTENT_TEMPLATE_TAG; |
