diff options
| author | 2018-10-15 17:21:17 +0000 | |
|---|---|---|
| committer | 2018-10-15 17:21:17 +0000 | |
| commit | 8aaf27259c410b718e0e20630a6c4a355f760cce (patch) | |
| tree | 5baa57a29eb14f2e454abb2e4a5b8e3eca464f00 | |
| parent | 6a1b4baf6b1da1886cd1b7ebd834dfeeb7873d67 (diff) | |
| parent | 9cc966012f55e4ceb561f4648642ed4ef80dc127 (diff) | |
Merge "Fixes touch ripples on media buttons."
7 files changed, 153 insertions, 31 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index b57a7d982960..4f41da6e52fb 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -20,6 +20,7 @@ import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast; import android.annotation.ColorInt; import android.annotation.DrawableRes; +import android.annotation.IdRes; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -37,6 +38,7 @@ import android.content.pm.ShortcutInfo; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -7759,8 +7761,17 @@ public class Notification implements Parcelable * @see Notification.Builder#setColorized(boolean) */ public static class MediaStyle extends Style { + // Changing max media buttons requires also changing templates + // (notification_template_material_media and notification_template_material_big_media). static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3; static final int MAX_MEDIA_BUTTONS = 5; + @IdRes private static final int[] MEDIA_BUTTON_IDS = { + R.id.action0, + R.id.action1, + R.id.action2, + R.id.action3, + R.id.action4, + }; private int[] mActionsToShowInCompact = null; private MediaSession.Token mToken; @@ -7874,15 +7885,16 @@ public class Notification implements Parcelable return false; } - private RemoteViews generateMediaActionButton(Action action, int color) { + private void bindMediaActionButton(RemoteViews container, @IdRes int buttonId, + Action action, int color) { final boolean tombstone = (action.actionIntent == null); - RemoteViews button = new BuilderRemoteViews(mBuilder.mContext.getApplicationInfo(), - R.layout.notification_material_media_action); - button.setImageViewIcon(R.id.action0, action.getIcon()); + container.setViewVisibility(buttonId, View.VISIBLE); + container.setImageViewIcon(buttonId, action.getIcon()); // If the action buttons should not be tinted, then just use the default // notification color. Otherwise, just use the passed-in color. - Configuration currentConfig = mBuilder.mContext.getResources().getConfiguration(); + Resources resources = mBuilder.mContext.getResources(); + Configuration currentConfig = resources.getConfiguration(); boolean inNightMode = (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; int tintColor = mBuilder.shouldTintActionButtons() || mBuilder.isColorized() @@ -7890,13 +7902,21 @@ public class Notification implements Parcelable : ContrastColorUtil.resolveColor(mBuilder.mContext, Notification.COLOR_DEFAULT, inNightMode); - button.setDrawableTint(R.id.action0, false, tintColor, + container.setDrawableTint(buttonId, false, tintColor, PorterDuff.Mode.SRC_ATOP); + + final TypedArray typedArray = mBuilder.mContext.obtainStyledAttributes( + new int[]{ android.R.attr.colorControlHighlight }); + int rippleAlpha = Color.alpha(typedArray.getColor(0, 0)); + typedArray.recycle(); + int rippleColor = Color.argb(rippleAlpha, Color.red(tintColor), Color.green(tintColor), + Color.blue(tintColor)); + container.setRippleDrawableColor(buttonId, ColorStateList.valueOf(rippleColor)); + if (!tombstone) { - button.setOnClickPendingIntent(R.id.action0, action.actionIntent); + container.setOnClickPendingIntent(buttonId, action.actionIntent); } - button.setContentDescription(R.id.action0, action.title); - return button; + container.setContentDescription(buttonId, action.title); } private RemoteViews makeMediaContentView() { @@ -7905,21 +7925,20 @@ public class Notification implements Parcelable null /* result */); final int numActions = mBuilder.mActions.size(); - final int N = mActionsToShowInCompact == null + final int numActionsToShow = mActionsToShowInCompact == null ? 0 : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT); - view.removeAllViews(com.android.internal.R.id.media_actions); - if (N > 0) { - for (int i = 0; i < N; i++) { - if (i >= numActions) { - throw new IllegalArgumentException(String.format( - "setShowActionsInCompactView: action %d out of bounds (max %d)", - i, numActions - 1)); - } - + if (numActionsToShow > numActions) { + throw new IllegalArgumentException(String.format( + "setShowActionsInCompactView: action %d out of bounds (max %d)", + numActions, numActions - 1)); + } + for (int i = 0; i < MAX_MEDIA_BUTTONS_IN_COMPACT; i++) { + if (i < numActionsToShow) { final Action action = mBuilder.mActions.get(mActionsToShowInCompact[i]); - final RemoteViews button = generateMediaActionButton(action, getActionColor()); - view.addView(com.android.internal.R.id.media_actions, button); + bindMediaActionButton(view, MEDIA_BUTTON_IDS[i], action, getActionColor()); + } else { + view.setViewVisibility(MEDIA_BUTTON_IDS[i], View.GONE); } } handleImage(view); @@ -7949,12 +7968,12 @@ public class Notification implements Parcelable RemoteViews big = mBuilder.applyStandardTemplate( R.layout.notification_template_material_big_media, false, null /* result */); - if (actionCount > 0) { - big.removeAllViews(com.android.internal.R.id.media_actions); - for (int i = 0; i < actionCount; i++) { - final RemoteViews button = generateMediaActionButton(mBuilder.mActions.get(i), + for (int i = 0; i < MAX_MEDIA_BUTTONS; i++) { + if (i < actionCount) { + bindMediaActionButton(big, MEDIA_BUTTON_IDS[i], mBuilder.mActions.get(i), getActionColor()); - big.addView(com.android.internal.R.id.media_actions, button); + } else { + big.setViewVisibility(MEDIA_BUTTON_IDS[i], View.GONE); } } handleImage(big); diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 35ff6cc23499..8f17e96c144e 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -42,6 +42,7 @@ import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; +import android.graphics.drawable.RippleDrawable; import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; @@ -152,6 +153,7 @@ public class RemoteViews implements Parcelable, Filter { private static final int SET_REMOTE_INPUTS_ACTION_TAG = 18; private static final int LAYOUT_PARAM_ACTION_TAG = 19; private static final int OVERRIDE_TEXT_COLORS_TAG = 20; + private static final int SET_RIPPLE_DRAWABLE_COLOR_TAG = 21; /** * Application that hosts the remote views. @@ -1122,6 +1124,53 @@ public class RemoteViews implements Parcelable, Filter { PorterDuff.Mode filterMode; } + /** + * Equivalent to calling + * {@link RippleDrawable#setColor(ColorStateList)}, + * on the {@link Drawable} of a given view. + * <p> + * The operation will be performed on the {@link Drawable} returned by the + * target {@link View#getBackground()}. + * <p> + */ + private class SetRippleDrawableColor extends Action { + + ColorStateList mColorStateList; + + SetRippleDrawableColor(int id, ColorStateList colorStateList) { + this.viewId = id; + this.mColorStateList = colorStateList; + } + + SetRippleDrawableColor(Parcel parcel) { + viewId = parcel.readInt(); + mColorStateList = parcel.readParcelable(null); + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(viewId); + dest.writeParcelable(mColorStateList, 0); + } + + @Override + public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + final View target = root.findViewById(viewId); + if (target == null) return; + + // Pick the correct drawable to modify for this view + Drawable targetDrawable = target.getBackground(); + + if (targetDrawable instanceof RippleDrawable) { + ((RippleDrawable) targetDrawable.mutate()).setColor(mColorStateList); + } + } + + @Override + public int getActionTag() { + return SET_RIPPLE_DRAWABLE_COLOR_TAG; + } + } + private final class ViewContentNavigation extends Action { final boolean mNext; @@ -2394,6 +2443,8 @@ public class RemoteViews implements Parcelable, Filter { return new LayoutParamAction(parcel); case OVERRIDE_TEXT_COLORS_TAG: return new OverrideTextColorsAction(parcel); + case SET_RIPPLE_DRAWABLE_COLOR_TAG: + return new SetRippleDrawableColor(parcel); default: throw new ActionException("Tag " + tag + " not found"); } @@ -2855,6 +2906,22 @@ public class RemoteViews implements Parcelable, Filter { /** * @hide + * Equivalent to calling + * {@link RippleDrawable#setColor(ColorStateList)} on the {@link Drawable} of a given view, + * assuming it's a {@link RippleDrawable}. + * <p> + * + * @param viewId The id of the view that contains the target + * {@link RippleDrawable} + * @param colorStateList Specify a color for a + * {@link ColorStateList} for this drawable. + */ + public void setRippleDrawableColor(int viewId, ColorStateList colorStateList) { + addAction(new SetRippleDrawableColor(viewId, colorStateList)); + } + + /** + * @hide * Equivalent to calling {@link android.widget.ProgressBar#setProgressTintList}. * * @param viewId The id of the view whose tint should change diff --git a/core/res/res/layout/notification_material_media_action.xml b/core/res/res/layout/notification_material_media_action.xml index 900ca2dd7667..dd79a0bb1817 100644 --- a/core/res/res/layout/notification_material_media_action.xml +++ b/core/res/res/layout/notification_material_media_action.xml @@ -18,7 +18,6 @@ <ImageButton xmlns:android="http://schemas.android.com/apk/res/android" style="@android:style/Widget.Material.Button.Borderless.Small" - android:id="@+id/action0" android:layout_width="@dimen/media_notification_action_button_size" android:layout_height="@dimen/media_notification_action_button_size" android:paddingBottom="8dp" @@ -28,4 +27,5 @@ android:layout_marginEnd="2dp" android:gravity="center" android:background="@drawable/notification_material_media_action_background" + android:visibility="gone" /> diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml index b4e26483a2ad..5cb93eb9319a 100644 --- a/core/res/res/layout/notification_template_material_big_media.xml +++ b/core/res/res/layout/notification_template_material_big_media.xml @@ -59,7 +59,26 @@ android:orientation="horizontal" android:layoutDirection="ltr" style="@style/NotificationMediaActionContainer" > - <!-- media buttons will be added here --> + <include + layout="@layout/notification_material_media_action" + android:id="@+id/action0" + /> + <include + layout="@layout/notification_material_media_action" + android:id="@+id/action1" + /> + <include + layout="@layout/notification_material_media_action" + android:id="@+id/action2" + /> + <include + layout="@layout/notification_material_media_action" + android:id="@+id/action3" + /> + <include + layout="@layout/notification_material_media_action" + android:id="@+id/action4" + /> </LinearLayout> </LinearLayout> </com.android.internal.widget.MediaNotificationView> diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml index 3a0912bd2a90..01b0866f428c 100644 --- a/core/res/res/layout/notification_template_material_media.xml +++ b/core/res/res/layout/notification_template_material_media.xml @@ -65,7 +65,18 @@ android:layoutDirection="ltr" android:orientation="horizontal" > - <!-- media buttons will be added here --> + <include + layout="@layout/notification_material_media_action" + android:id="@+id/action0" + /> + <include + layout="@layout/notification_material_media_action" + android:id="@+id/action1" + /> + <include + layout="@layout/notification_material_media_action" + android:id="@+id/action2" + /> </LinearLayout> </LinearLayout> </FrameLayout> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 11f5e9023507..09da4fcd3f4e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -186,6 +186,8 @@ <java-symbol type="id" name="action0" /> <java-symbol type="id" name="action1" /> <java-symbol type="id" name="action2" /> + <java-symbol type="id" name="action3" /> + <java-symbol type="id" name="action4" /> <java-symbol type="id" name="big_picture" /> <java-symbol type="id" name="big_text" /> <java-symbol type="id" name="chronometer" /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java index 2ca7282041cc..f76284dd1ffc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.row.wrapper; import android.content.Context; +import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.view.NotificationHeaderView; @@ -76,8 +77,11 @@ public abstract class NotificationViewWrapper implements TransformableView { } Drawable background = mView.getBackground(); if (background instanceof ColorDrawable) { - mBackgroundColor = ((ColorDrawable) background).getColor(); - mView.setBackground(null); + int backgroundColor = ((ColorDrawable) background).getColor(); + if (backgroundColor != Color.TRANSPARENT) { + mBackgroundColor = backgroundColor; + mView.setBackground(new ColorDrawable(Color.TRANSPARENT)); + } } } |