diff options
11 files changed, 207 insertions, 117 deletions
diff --git a/packages/SystemUI/res/layout/notification_snooze.xml b/packages/SystemUI/res/layout/notification_snooze.xml index 5bd64defd2d1..b70f24b4d552 100644 --- a/packages/SystemUI/res/layout/notification_snooze.xml +++ b/packages/SystemUI/res/layout/notification_snooze.xml @@ -19,47 +19,56 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="@dimen/snooze_snackbar_min_height" - android:id="@+id/notification_snooze" - android:clickable="true" - android:gravity="center_vertical" - android:orientation="horizontal" - android:paddingStart="24dp" - android:paddingEnd="24dp" - android:background="@color/snooze_snackbar_bg"> - - <TextView - android:id="@+id/snooze_option_default" - style="@style/TextAppearance.SnoozeSnackBar" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:gravity="center_vertical" - android:drawableTint="@android:color/white" - android:drawableEnd="@drawable/notification_expand_more"/> - - <android.widget.Space - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_weight="1" - /> - - <TextView - android:id="@+id/undo" - style="@style/TextAppearance.SnoozeSnackBar.Button" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_marginEnd="8dp" - android:layout_marginStart="8dp" - android:background="@drawable/btn_borderless_rect" - android:layout_gravity="end" - android:text="@string/snooze_undo" /> - + android:orientation="vertical" + android:background="@color/notification_guts_bg_color" + android:theme="@*android:style/Theme.DeviceDefault.Light"> + + <RelativeLayout + android:layout_width="match_parent" + android:id="@+id/notification_snooze" + android:layout_height="@dimen/snooze_snackbar_min_height"> + + <TextView + android:id="@+id/snooze_option_default" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_centerVertical="true" + android:paddingStart="16dp" + android:textColor="#DD000000" + android:paddingEnd="4dp"/> + + <ImageView + android:id="@+id/expand_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toEndOf="@+id/snooze_option_default" + android:layout_centerVertical="true" + android:paddingTop="1dp" + android:tint="#9E9E9E" /> + + <TextView + android:id="@+id/undo" + style="@style/TextAppearance.NotificationInfo.Button" + android:layout_width="wrap_content" + android:layout_height="36dp" + android:layout_marginEnd="8dp" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:text="@string/snooze_undo" /> + </RelativeLayout> + + <View + android:id="@+id/divider" + android:layout_width="match_parent" + android:layout_height="0.5dp" + android:background="#9E9E9E" /> + <LinearLayout android:id="@+id/snooze_options" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="8dp" android:paddingBottom="8dp" - android:orientation="vertical"/> - + android:orientation="vertical" /> + </com.android.systemui.statusbar.NotificationSnooze> diff --git a/packages/SystemUI/res/layout/notification_snooze_option.xml b/packages/SystemUI/res/layout/notification_snooze_option.xml new file mode 100644 index 000000000000..aaf45f34585b --- /dev/null +++ b/packages/SystemUI/res/layout/notification_snooze_option.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2017, 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. +--> +<TextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="48dp" + android:layout_marginStart="@*android:dimen/notification_content_margin_start" + android:layout_marginEnd="@*android:dimen/notification_content_margin_end" + android:gravity="center_vertical" + android:textSize="14sp" + android:textColor="#DD000000"/>
\ No newline at end of file diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index f461bb3ffedf..83a0b7bcdc65 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -96,10 +96,6 @@ <!-- The "inside" of a notification, reached via longpress --> <color name="notification_guts_bg_color">#eeeeee</color> - <!-- Colors of the snooze menu reached via snooze icon behind a notification --> - <color name="snooze_snackbar_bg">#FF4A4A4A</color> - <color name="snooze_snackbar_text">#FFA6BAFF</color> - <color name="assist_orb_color">#ffffff</color> <color name="keyguard_user_switcher_background_gradient_color">#77000000</color> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 1a3e6ce16985..4edadea38a93 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -119,7 +119,7 @@ <dimen name="notification_menu_icon_padding">20dp</dimen> <!-- The minimum height for the snackbar shown after the snooze option has been chosen. --> - <dimen name="snooze_snackbar_min_height">48dp</dimen> + <dimen name="snooze_snackbar_min_height">56dp</dimen> <!-- The text size of options in the snooze menu. --> <dimen name="snooze_option_text_size">14sp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index b87da27ea632..5f88773de424 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1502,8 +1502,6 @@ <string name="snooze_option_30_min">30 minutes</string> <!-- Notification: Menu row: Snooze options: 1 hour option. [CHAR LIMIT=50]--> <string name="snooze_option_1_hour">1 hour</string> - <!-- Notification: Menu row: Snooze options: cancel snoozing option. [CHAR LIMIT=50] --> - <string name="snooze_option_dont_snooze">Cancel</string> <!-- Notification: Menu row: Snooze undo button label. [CHAR LIMIT=50]--> <string name="snooze_undo">UNDO</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index e5f04c6186b8..dbdbd1e287aa 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -386,20 +386,6 @@ <item name="android:paddingEnd">8dp</item> </style> - <style name="TextAppearance.SnoozeSnackBar"> - <item name="android:textSize">14sp</item> - <item name="android:fontFamily">sans-serif</item> - <item name="android:textColor">@android:color/white</item> - </style> - - <style name="TextAppearance.SnoozeSnackBar.Button"> - <item name="android:textSize">14sp</item> - <item name="android:textAllCaps">true</item> - <item name="android:fontFamily">sans-serif-medium</item> - <item name="android:gravity">center</item> - <item name="android:textColor">@color/snooze_snackbar_text</item> - </style> - <style name="edit_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings"> <item name="android:colorBackground">?android:attr/colorSecondary</item> </style> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index cc9175382903..dff09bda8844 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1494,7 +1494,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return getActualHeight(); } if (mGuts != null && mGuts.isExposed()) { - return mGuts.getHeight(); + return mGuts.getIntrinsicHeight(); } else if ((isChildInGroup() && !isGroupExpanded())) { return mPrivateLayout.getMinHeight(); } else if (mShowAmbient) { @@ -1835,7 +1835,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView @Override public int getMinHeight() { - if (!mOnKeyguard && mIsHeadsUp && mHeadsUpManager.isTrackingHeadsUp()) { + if (mGuts != null && mGuts.isExposed()) { + return mGuts.getIntrinsicHeight(); + } else if (!mOnKeyguard && mIsHeadsUp && mHeadsUpManager.isTrackingHeadsUp()) { return getPinnedHeadsUpHeight(false /* atLeastMinHeight */); } else if (mIsSummaryWithChildren && !isGroupExpanded() && !mShowingPublic) { return mChildrenContainer.getMinHeight(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java index 0a99ee6c781f..137531079a12 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java @@ -74,7 +74,8 @@ public class NotificationGuts extends FrameLayout { private Handler mHandler; private Runnable mFalsingCheck; private boolean mNeedsFalsingProtection; - private OnGutsClosedListener mListener; + private OnGutsClosedListener mClosedListener; + private OnHeightChangedListener mHeightListener; private GutsContent mGutsContent; @@ -88,6 +89,11 @@ public class NotificationGuts extends FrameLayout { public View getContentView(); /** + * @return the actual height of the content. + */ + public int getActualHeight(); + + /** * Called when the guts view have been told to close, typically after an outside * interaction. Returning {@code true} here will prevent the guts view to close. */ @@ -103,6 +109,10 @@ public class NotificationGuts extends FrameLayout { public void onGutsClosed(NotificationGuts guts); } + public interface OnHeightChangedListener { + public void onHeightChanged(NotificationGuts guts); + } + interface OnSettingsClickListener { void onClick(View v, int appUid); } @@ -126,7 +136,6 @@ public class NotificationGuts extends FrameLayout { public NotificationGuts(Context context) { this(context, null); - } public void setGutsContent(GutsContent content) { @@ -190,8 +199,8 @@ public class NotificationGuts extends FrameLayout { public void closeControls(int x, int y, boolean save) { if (getWindowToken() == null) { - if (mListener != null) { - mListener.onGutsClosed(this); + if (mClosedListener != null) { + mClosedListener.onGutsClosed(this); } return; } @@ -199,8 +208,8 @@ public class NotificationGuts extends FrameLayout { animateClose(x, y); } setExposed(false, mNeedsFalsingProtection); - if (mListener != null) { - mListener.onGutsClosed(this); + if (mClosedListener != null) { + mClosedListener.onGutsClosed(this); } } @@ -235,6 +244,10 @@ public class NotificationGuts extends FrameLayout { return mActualHeight; } + public int getIntrinsicHeight() { + return mGutsContent != null && mExposed ? mGutsContent.getActualHeight() : getHeight(); + } + public void setClipTopAmount(int clipTopAmount) { mClipTopAmount = clipTopAmount; invalidate(); @@ -252,7 +265,17 @@ public class NotificationGuts extends FrameLayout { } public void setClosedListener(OnGutsClosedListener listener) { - mListener = listener; + mClosedListener = listener; + } + + public void setHeightChangedListener(OnHeightChangedListener listener) { + mHeightListener = listener; + } + + protected void onHeightChanged() { + if (mHeightListener != null) { + mHeightListener.onHeightChanged(this); + } } public void setExposed(boolean exposed, boolean needsFalsingProtection) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java index 89251897e25f..f3c7b8495a01 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java @@ -403,4 +403,9 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G } return false; } + + @Override + public int getActualHeight() { + return getHeight(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java index 4a3f112f0406..ccc99c59e510 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java @@ -21,35 +21,47 @@ import java.util.List; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.Resources; -import android.graphics.Color; +import android.graphics.Typeface; import android.service.notification.SnoozeCriterion; import android.service.notification.StatusBarNotification; +import android.text.SpannableString; +import android.text.style.StyleSpan; import android.util.AttributeSet; import android.util.Log; -import android.util.TypedValue; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; + +import com.android.systemui.Interpolators; import com.android.systemui.R; public class NotificationSnooze extends LinearLayout implements NotificationGuts.GutsContent, View.OnClickListener { - private static final int MAX_ASSISTANT_SUGGESTIONS = 2; + private static final int MAX_ASSISTANT_SUGGESTIONS = 1; private NotificationGuts mGutsContainer; private NotificationSwipeActionHelper mSnoozeListener; private StatusBarNotification mSbn; private TextView mSelectedOptionText; private TextView mUndoButton; - private ViewGroup mSnoozeOptionView; + private ImageView mExpandButton; + private View mDivider; + private ViewGroup mSnoozeOptionContainer; private List<SnoozeOption> mSnoozeOptions; - private boolean mSnoozing; + private int mCollapsedHeight; private SnoozeOption mSelectedOption; + private boolean mSnoozing; + private boolean mExpanded; + private AnimatorSet mExpandAnimation; public NotificationSnooze(Context context, AttributeSet attrs) { super(context, attrs); @@ -58,16 +70,21 @@ public class NotificationSnooze extends LinearLayout @Override protected void onFinishInflate() { super.onFinishInflate(); + mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.snooze_snackbar_min_height); + findViewById(R.id.notification_snooze).setOnClickListener(this); + mSelectedOptionText = (TextView) findViewById(R.id.snooze_option_default); + mUndoButton = (TextView) findViewById(R.id.undo); + mUndoButton.setOnClickListener(this); + mExpandButton = (ImageView) findViewById(R.id.expand_button); + mDivider = findViewById(R.id.divider); + mDivider.setAlpha(0f); + mSnoozeOptionContainer = (ViewGroup) findViewById(R.id.snooze_options); + mSnoozeOptionContainer.setAlpha(0f); + // Create the different options based on list mSnoozeOptions = getDefaultSnoozeOptions(); createOptionViews(); - // Snackbar - mSelectedOptionText = findViewById(R.id.snooze_option_default); - mSelectedOptionText.setOnClickListener(this); - mUndoButton = findViewById(R.id.undo); - mUndoButton.setOnClickListener(this); - // Default to first option in list setSelected(mSnoozeOptions.get(0)); } @@ -96,52 +113,68 @@ public class NotificationSnooze extends LinearLayout private SnoozeOption createOption(int descriptionResId, int minutes) { Resources res = getResources(); - String resultText = String.format( - res.getString(R.string.snoozed_for_time), res.getString(descriptionResId)); - return new SnoozeOption(null, minutes, res.getString(descriptionResId), resultText); + final String description = res.getString(descriptionResId); + String resultText = String.format(res.getString(R.string.snoozed_for_time), description); + SpannableString string = new SpannableString(resultText); + string.setSpan(new StyleSpan(Typeface.BOLD), + resultText.length() - description.length(), resultText.length(), 0 /* flags */); + return new SnoozeOption(null, minutes, res.getString(descriptionResId), string); } private void createOptionViews() { - mSnoozeOptionView = findViewById(R.id.snooze_options); - mSnoozeOptionView.removeAllViews(); - mSnoozeOptionView.setVisibility(View.GONE); - final Resources res = getResources(); - final int textSize = res.getDimensionPixelSize(R.dimen.snooze_option_text_size); - final int p = res.getDimensionPixelSize(R.dimen.snooze_option_padding); - - // Add all the options + mSnoozeOptionContainer.removeAllViews(); + LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( + Context.LAYOUT_INFLATER_SERVICE); for (int i = 0; i < mSnoozeOptions.size(); i++) { SnoozeOption option = mSnoozeOptions.get(i); - TextView tv = new TextView(getContext()); - tv.setTextColor(Color.WHITE); - tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); - tv.setPadding(p, p, p, p); - mSnoozeOptionView.addView(tv); + TextView tv = (TextView) inflater.inflate(R.layout.notification_snooze_option, + mSnoozeOptionContainer, false); + mSnoozeOptionContainer.addView(tv); tv.setText(option.description); tv.setTag(option); tv.setOnClickListener(this); } + } - // Add the undo option as final item - TextView tv = new TextView(getContext()); - tv.setTextColor(Color.WHITE); - tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); - tv.setPadding(p, p, p, p); - mSnoozeOptionView.addView(tv); - tv.setText(R.string.snooze_option_dont_snooze); - tv.setOnClickListener(this); + private void hideSelectedOption() { + final int childCount = mSnoozeOptionContainer.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = mSnoozeOptionContainer.getChildAt(i); + child.setVisibility(child.getTag() == mSelectedOption ? View.GONE : View.VISIBLE); + } } private void showSnoozeOptions(boolean show) { - mSelectedOptionText.setVisibility(show ? View.GONE : View.VISIBLE); - mUndoButton.setVisibility(show ? View.GONE : View.VISIBLE); - mSnoozeOptionView.setVisibility(show ? View.VISIBLE : View.GONE); + mExpanded = show; + animateSnoozeOptions(show); + int drawableId = show ? com.android.internal.R.drawable.ic_collapse_notification + : com.android.internal.R.drawable.ic_expand_notification; + mExpandButton.setImageResource(drawableId); + if (mGutsContainer != null) { + mGutsContainer.onHeightChanged(); + } + } + + private void animateSnoozeOptions(boolean show) { + if (mExpandAnimation != null) { + mExpandAnimation.cancel(); + } + ObjectAnimator dividerAnim = ObjectAnimator.ofFloat(mDivider, View.ALPHA, + mDivider.getAlpha(), show ? 1f : 0f); + ObjectAnimator optionAnim = ObjectAnimator.ofFloat(mSnoozeOptionContainer, View.ALPHA, + mSnoozeOptionContainer.getAlpha(), show ? 1f : 0f); + mExpandAnimation = new AnimatorSet(); + mExpandAnimation.playTogether(dividerAnim, optionAnim); + mExpandAnimation.setDuration(150); + mExpandAnimation.setInterpolator(show ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT); + mExpandAnimation.start(); } private void setSelected(SnoozeOption option) { mSelectedOption = option; mSelectedOptionText.setText(option.confirmation); showSnoozeOptions(false); + hideSelectedOption(); } @Override @@ -153,17 +186,28 @@ public class NotificationSnooze extends LinearLayout final SnoozeOption tag = (SnoozeOption) v.getTag(); if (tag != null) { setSelected(tag); - } else if (id == R.id.snooze_option_default) { - // Show more snooze options - showSnoozeOptions(true); + } else if (id == R.id.notification_snooze) { + // Toggle snooze options + showSnoozeOptions(!mExpanded); } else { - undoSnooze(); + // Undo snooze was selected + mSelectedOption = null; + int[] parentLoc = new int[2]; + int[] targetLoc = new int[2]; + mGutsContainer.getLocationOnScreen(parentLoc); + v.getLocationOnScreen(targetLoc); + final int centerX = v.getWidth() / 2; + final int centerY = v.getHeight() / 2; + final int x = targetLoc[0] - parentLoc[0] + centerX; + final int y = targetLoc[1] - parentLoc[1] + centerY; + showSnoozeOptions(false); + mGutsContainer.closeControls(x, y, false /* save */); } } - private void undoSnooze() { - mSelectedOption = null; - mGutsContainer.closeControls(-1 /* x */, -1 /* y */, true /* notify */); + @Override + public int getActualHeight() { + return mExpanded ? getHeight() : mCollapsedHeight; } @Override @@ -173,6 +217,8 @@ public class NotificationSnooze extends LinearLayout @Override public View getContentView() { + // Reset the view before use + setSelected(mSnoozeOptions.get(0)); return this; } @@ -197,11 +243,8 @@ public class NotificationSnooze extends LinearLayout mSnoozing = true; mSnoozeListener.snooze(mSbn, mSelectedOption); return true; - } else { - // Reset the view once it's closed - setSelected(mSnoozeOptions.get(0)); - showSnoozeOptions(false); } + // The view should be closed return false; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 79191f3c2114..46d64153d04d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -5774,6 +5774,9 @@ public class StatusBar extends SystemUI implements DemoMode, snoozeGuts.setSnoozeListener(mStackScroller.getSwipeActionHelper()); snoozeGuts.setStatusBarNotification(sbn); snoozeGuts.setSnoozeOptions(row.getEntry().snoozeCriteria); + guts.setHeightChangedListener((NotificationGuts g) -> { + mStackScroller.onHeightChanged(row, row.isShown() /* needsAnimation */); + }); } if (gutsView instanceof NotificationInfo) { |