Show largeIcon on the left when grouped.

* The icon is smaller when shown on the left.
* This only happens when grouping logic hides the notification icon (same icon/color for all children in the group).
* Does not apply to messaging layouts.

Bug: 163626038
Test: manual
Change-Id: I4c7db076db11ccc69f2907bbb441ff3bc06078f2
This commit is contained in:
Jeff DeCew
2020-11-25 12:02:06 -05:00
parent 7afa84bb4d
commit b00728fd4a
10 changed files with 270 additions and 123 deletions

View File

@@ -30,6 +30,7 @@ import android.annotation.IdRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Px;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -5105,33 +5106,29 @@ public class Notification implements Parcelable
if (result == null) {
result = new TemplateBindResult();
}
boolean largeIconShown = bindLargeIcon(contentView, p);
final boolean largeIconShown = bindLargeIcon(contentView, p);
calculateLargeIconMarginEnd(largeIconShown, result);
if (p.mHeaderless) {
// views in the headerless (collapsed) state
contentView.setViewLayoutMarginEnd(R.id.notification_standard_view_column,
result.getHeadingExtraMarginEnd());
result.mHeadingExtraMarginSet.applyToView(contentView,
R.id.notification_headerless_view_column);
} else {
// views in states with a header (big states)
contentView.setInt(R.id.notification_header, "setTopLineExtraMarginEnd",
result.getHeadingExtraMarginEnd());
contentView.setViewLayoutMarginEnd(R.id.line1, result.getTitleMarginEnd());
result.mHeadingExtraMarginSet.applyToView(contentView, R.id.notification_header);
result.mTitleMarginSet.applyToView(contentView, R.id.line1);
}
}
private void calculateLargeIconMarginEnd(boolean largeIconShown,
@NonNull TemplateBindResult result) {
int contentMargin = mContext.getResources().getDimensionPixelSize(
final Resources resources = mContext.getResources();
final int contentMargin = resources.getDimensionPixelOffset(
R.dimen.notification_content_margin_end);
int expanderSize = mContext.getResources().getDimensionPixelSize(
final int expanderSize = resources.getDimensionPixelSize(
R.dimen.notification_header_expand_icon_size) - contentMargin;
int extraMarginEnd = 0;
if (largeIconShown) {
int iconSize = mContext.getResources().getDimensionPixelSize(
R.dimen.notification_right_icon_size);
extraMarginEnd = iconSize + contentMargin;
}
result.setRightIconState(largeIconShown, extraMarginEnd, expanderSize);
final int extraMarginEndIfVisible = resources.getDimensionPixelSize(
R.dimen.notification_right_icon_size) + contentMargin;
result.setRightIconState(largeIconShown, extraMarginEndIfVisible, expanderSize);
}
/**
@@ -7759,8 +7756,10 @@ public class Notification implements Parcelable
addExtras(mBuilder.mN.extras);
if (!isConversationLayout) {
// also update the end margin if there is an image
// NOTE: This template doesn't support moving this icon to the left, so we don't
// need to fully apply the MarginSet
contentView.setViewLayoutMarginEnd(R.id.notification_messaging,
bindResult.getHeadingExtraMarginEnd());
bindResult.mHeadingExtraMarginSet.getValue());
}
contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
mBuilder.isColorized(p)
@@ -8757,9 +8756,8 @@ public class Notification implements Parcelable
if (!headerless) {
// also update the end margin to account for the large icon or expander
Resources resources = mBuilder.mContext.getResources();
int endMargin = resources.getDimensionPixelSize(
R.dimen.notification_content_margin_end) + result.getTitleMarginEnd();
remoteViews.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin);
result.mTitleMarginSet.applyToView(remoteViews, R.id.notification_main_column,
resources.getDimensionPixelOffset(R.dimen.notification_content_margin_end));
}
}
@@ -10997,42 +10995,74 @@ public class Notification implements Parcelable
*/
private static class TemplateBindResult {
boolean mRightIconVisible;
int mRightIconMarginEnd;
int mExpanderSize;
/**
* @return the margin end that needs to be added to the heading so that it won't overlap
* The margin end that needs to be added to the heading so that it won't overlap
* with the large icon. This value includes the space required to accommodate the large
* icon, but should be added to the space needed to accommodate the expander. This does
* not include the 16dp content margin that all notification views must have.
*/
public int getHeadingExtraMarginEnd() {
return mRightIconMarginEnd;
}
public final MarginSet mHeadingExtraMarginSet = new MarginSet();
/**
* @return the margin end that needs to be added to the heading so that it won't overlap
* The margin end that needs to be added to the heading so that it won't overlap
* with the large icon. This value includes the space required to accommodate the large
* icon as well as the expander. This does not include the 16dp content margin that all
* notification views must have.
*/
public int getHeadingFullMarginEnd() {
return mRightIconMarginEnd + mExpanderSize;
}
public final MarginSet mHeadingFullMarginSet = new MarginSet();
/**
* @return the margin end that needs to be added to the title text of the big state
* The margin end that needs to be added to the title text of the big state
* so that it won't overlap with the large icon, but assuming the text can run under
* the expander when that icon is not visible.
*/
public int getTitleMarginEnd() {
return mRightIconVisible ? getHeadingFullMarginEnd() : 0;
public final MarginSet mTitleMarginSet = new MarginSet();
public void setRightIconState(boolean visible, int marginEndIfVisible, int expanderSize) {
mRightIconVisible = visible;
mHeadingExtraMarginSet.setValues(0, marginEndIfVisible);
mHeadingFullMarginSet.setValues(expanderSize, marginEndIfVisible + expanderSize);
mTitleMarginSet.setValues(0, marginEndIfVisible + expanderSize);
}
public void setRightIconState(boolean visible, int marginEnd, int expanderSize) {
mRightIconVisible = visible;
mRightIconMarginEnd = marginEnd;
mExpanderSize = expanderSize;
/**
* This contains the end margins for a view when the right icon is visible or not. These
* values are both needed so that NotificationGroupingUtil can 'move' the right_icon to the
* left_icon and adjust the margins, and to undo that change as well.
*/
private class MarginSet {
private int mValueIfGone;
private int mValueIfVisible;
public void setValues(int valueIfGone, int valueIfVisible) {
mValueIfGone = valueIfGone;
mValueIfVisible = valueIfVisible;
}
public void applyToView(@NonNull RemoteViews views, @IdRes int viewId) {
applyToView(views, viewId, 0);
}
public void applyToView(@NonNull RemoteViews views, @IdRes int viewId,
@Px int extraMargin) {
final int marginEnd = getValue() + extraMargin;
if (viewId == R.id.notification_header) {
views.setInt(R.id.notification_header, "setTopLineExtraMarginEnd", marginEnd);
} else {
views.setViewLayoutMarginEnd(viewId, marginEnd);
}
if (mRightIconVisible) {
views.setIntTag(viewId, R.id.tag_margin_end_when_icon_visible,
mValueIfVisible + extraMargin);
views.setIntTag(viewId, R.id.tag_margin_end_when_icon_gone,
mValueIfGone + extraMargin);
}
}
public int getValue() {
return mRightIconVisible ? mValueIfVisible : mValueIfGone;
}
}
}

View File

@@ -26,6 +26,18 @@
android:theme="@style/Theme.DeviceDefault.Notification"
>
<ImageView
android:id="@+id/left_icon"
android:layout_width="@dimen/notification_left_icon_size"
android:layout_height="@dimen/notification_left_icon_size"
android:layout_gravity="center_vertical|start"
android:layout_marginStart="@dimen/notification_left_icon_start"
android:background="@drawable/notification_large_icon_outline"
android:importantForAccessibility="no"
android:scaleType="centerCrop"
android:visibility="gone"
/>
<com.android.internal.widget.CachingIconView
android:id="@+id/icon"
android:layout_width="@dimen/notification_icon_circle_size"

View File

@@ -23,6 +23,18 @@
android:tag="base"
>
<ImageView
android:id="@+id/left_icon"
android:layout_width="@dimen/notification_left_icon_size"
android:layout_height="@dimen/notification_left_icon_size"
android:layout_gravity="center_vertical|start"
android:layout_marginStart="@dimen/notification_left_icon_start"
android:background="@drawable/notification_large_icon_outline"
android:importantForAccessibility="no"
android:scaleType="centerCrop"
android:visibility="gone"
/>
<com.android.internal.widget.CachingIconView
android:id="@+id/icon"
android:layout_width="@dimen/notification_icon_circle_size"
@@ -34,7 +46,7 @@
/>
<LinearLayout
android:id="@+id/notification_standard_view_column"
android:id="@+id/notification_headerless_view_column"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"

View File

@@ -714,6 +714,10 @@
<dimen name="notification_right_icon_headerless_margin">12dp</dimen>
<!-- The top margin of the right icon in the "big" notification states -->
<dimen name="notification_right_icon_big_margin_top">16dp</dimen>
<!-- The size of the left icon -->
<dimen name="notification_left_icon_size">@dimen/notification_icon_circle_size</dimen>
<!-- The left padding of the left icon -->
<dimen name="notification_left_icon_start">@dimen/notification_icon_circle_start</dimen>
<!-- The alpha of a disabled notification button -->
<item type="dimen" format="float" name="notification_action_disabled_alpha">0.5</item>

View File

@@ -194,6 +194,12 @@
<!-- A tag used to save the index where the custom view is stored -->
<item type="id" name="notification_custom_view_index_tag" />
<!-- A tag used to store the margin end for this view when the right icon is visible -->
<item type="id" name="tag_margin_end_when_icon_gone" />
<!-- A tag used to store the margin end for this view when the right icon is gone -->
<item type="id" name="tag_margin_end_when_icon_visible" />
<!-- Marks the "copy to clipboard" button in the ChooserActivity -->
<item type="id" name="chooser_copy_button" />

View File

@@ -218,7 +218,7 @@
<java-symbol type="id" name="inbox_text6" />
<java-symbol type="id" name="status_bar_latest_event_content" />
<java-symbol type="id" name="notification_main_column" />
<java-symbol type="id" name="notification_standard_view_column" />
<java-symbol type="id" name="notification_headerless_view_column" />
<java-symbol type="id" name="sms_short_code_confirm_message" />
<java-symbol type="id" name="sms_short_code_detail_layout" />
<java-symbol type="id" name="sms_short_code_detail_message" />
@@ -3070,6 +3070,8 @@
<java-symbol type="dimen" name="notification_media_image_margin_end" />
<java-symbol type="id" name="notification_action_list_margin_target" />
<java-symbol type="dimen" name="notification_action_disabled_alpha" />
<java-symbol type="id" name="tag_margin_end_when_icon_visible" />
<java-symbol type="id" name="tag_margin_end_when_icon_gone" />
<!-- Override Wake Key Behavior When Screen is Off -->
<java-symbol type="bool" name="config_wakeOnDpadKeyPress" />

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2020 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.
@@ -11,19 +11,22 @@
* 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
* limitations under the License.
*/
package com.android.systemui.statusbar;
import android.app.Notification;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.text.TextUtils;
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.ConversationLayout;
import com.android.internal.widget.NotificationExpandButton;
@@ -36,35 +39,38 @@ import java.util.List;
import java.util.Objects;
/**
* A Util to manage {@link android.view.NotificationHeaderView} objects and their redundancies.
* A utility to manage notification views when they are placed in a group by adjusting elements
* to reduce redundancies and occasionally tweak layouts to highlight the unique content.
*/
public class NotificationHeaderUtil {
public class NotificationGroupingUtil {
private static final TextViewComparator sTextViewComparator = new TextViewComparator();
private static final TextViewComparator sAppNameComparator = new AppNameComparator();
private static final VisibilityApplicator sVisibilityApplicator = new VisibilityApplicator();
private static final VisibilityApplicator sAppNameApplicator = new AppNameApplicator();
private static final DataExtractor sIconExtractor = new DataExtractor() {
private static final TextViewComparator TEXT_VIEW_COMPARATOR = new TextViewComparator();
private static final TextViewComparator APP_NAME_COMPARATOR = new AppNameComparator();
private static final ViewComparator BADGE_COMPARATOR = new BadgeComparator();
private static final VisibilityApplicator VISIBILITY_APPLICATOR = new VisibilityApplicator();
private static final VisibilityApplicator APP_NAME_APPLICATOR = new AppNameApplicator();
private static final ResultApplicator LEFT_ICON_APPLICATOR = new LeftIconApplicator();
private static final DataExtractor ICON_EXTRACTOR = new DataExtractor() {
@Override
public Object extractData(ExpandableNotificationRow row) {
return row.getEntry().getSbn().getNotification();
}
};
private static final IconComparator sIconVisibilityComparator = new IconComparator() {
private static final IconComparator ICON_VISIBILITY_COMPARATOR = new IconComparator() {
public boolean compare(View parent, View child, Object parentData,
Object childData) {
return hasSameIcon(parentData, childData)
&& hasSameColor(parentData, childData);
}
};
private static final IconComparator sGreyComparator = new IconComparator() {
private static final IconComparator GREY_COMPARATOR = new IconComparator() {
public boolean compare(View parent, View child, Object parentData,
Object childData) {
return !hasSameIcon(parentData, childData)
|| hasSameColor(parentData, childData);
}
};
private final static ResultApplicator mGreyApplicator = new ResultApplicator() {
private static final ResultApplicator GREY_APPLICATOR = new ResultApplicator() {
@Override
public void apply(View parent, View view, boolean apply, boolean reset) {
CachingIconView icon = view.findViewById(com.android.internal.R.id.icon);
@@ -80,87 +86,79 @@ public class NotificationHeaderUtil {
};
private final ExpandableNotificationRow mRow;
private final ArrayList<HeaderProcessor> mComparators = new ArrayList<>();
private final ArrayList<Processor> mProcessors = new ArrayList<>();
private final HashSet<Integer> mDividers = new HashSet<>();
public NotificationHeaderUtil(ExpandableNotificationRow row) {
public NotificationGroupingUtil(ExpandableNotificationRow row) {
mRow = row;
// To hide the icons if they are the same and the color is the same
mComparators.add(new HeaderProcessor(mRow,
mProcessors.add(new Processor(mRow,
com.android.internal.R.id.icon,
sIconExtractor,
sIconVisibilityComparator,
sVisibilityApplicator));
ICON_EXTRACTOR,
ICON_VISIBILITY_COMPARATOR,
VISIBILITY_APPLICATOR));
// To grey them out the icons and expand button when the icons are not the same
mComparators.add(new HeaderProcessor(mRow,
com.android.internal.R.id.notification_header,
sIconExtractor,
sGreyComparator,
mGreyApplicator));
mComparators.add(new HeaderProcessor(mRow,
mProcessors.add(new Processor(mRow,
com.android.internal.R.id.status_bar_latest_event_content,
ICON_EXTRACTOR,
GREY_COMPARATOR,
GREY_APPLICATOR));
mProcessors.add(new Processor(mRow,
com.android.internal.R.id.status_bar_latest_event_content,
ICON_EXTRACTOR,
ICON_VISIBILITY_COMPARATOR,
LEFT_ICON_APPLICATOR));
mProcessors.add(new Processor(mRow,
com.android.internal.R.id.profile_badge,
null /* Extractor */,
new ViewComparator() {
@Override
public boolean compare(View parent, View child, Object parentData,
Object childData) {
return parent.getVisibility() != View.GONE;
}
@Override
public boolean isEmpty(View view) {
if (view instanceof ImageView) {
return ((ImageView) view).getDrawable() == null;
}
return false;
}
},
sVisibilityApplicator));
mComparators.add(new HeaderProcessor(
mRow,
BADGE_COMPARATOR,
VISIBILITY_APPLICATOR));
mProcessors.add(new Processor(mRow,
com.android.internal.R.id.app_name_text,
null,
sAppNameComparator,
sAppNameApplicator));
mComparators.add(HeaderProcessor.forTextView(mRow,
com.android.internal.R.id.header_text));
APP_NAME_COMPARATOR,
APP_NAME_APPLICATOR));
mProcessors.add(Processor.forTextView(mRow, com.android.internal.R.id.header_text));
mDividers.add(com.android.internal.R.id.header_text_divider);
mDividers.add(com.android.internal.R.id.header_text_secondary_divider);
mDividers.add(com.android.internal.R.id.time_divider);
}
public void updateChildrenHeaderAppearance() {
/**
* Update the appearance of the children in this group to reduce redundancies.
*/
public void updateChildrenAppearance() {
List<ExpandableNotificationRow> notificationChildren = mRow.getAttachedChildren();
if (notificationChildren == null) {
return;
}
// Initialize the comparators
for (int compI = 0; compI < mComparators.size(); compI++) {
mComparators.get(compI).init();
// Initialize the processors
for (int compI = 0; compI < mProcessors.size(); compI++) {
mProcessors.get(compI).init();
}
// Compare all notification headers
for (int i = 0; i < notificationChildren.size(); i++) {
ExpandableNotificationRow row = notificationChildren.get(i);
for (int compI = 0; compI < mComparators.size(); compI++) {
mComparators.get(compI).compareToHeader(row);
for (int compI = 0; compI < mProcessors.size(); compI++) {
mProcessors.get(compI).compareToGroupParent(row);
}
}
// Apply the comparison to the row
for (int i = 0; i < notificationChildren.size(); i++) {
ExpandableNotificationRow row = notificationChildren.get(i);
for (int compI = 0; compI < mComparators.size(); compI++) {
mComparators.get(compI).apply(row);
for (int compI = 0; compI < mProcessors.size(); compI++) {
mProcessors.get(compI).apply(row);
}
// We need to sanitize the dividers since they might be off-balance now
sanitizeHeaderViews(row);
sanitizeTopLineViews(row);
}
}
private void sanitizeHeaderViews(ExpandableNotificationRow row) {
private void sanitizeTopLineViews(ExpandableNotificationRow row) {
if (row.isSummaryWithChildren()) {
sanitizeHeader(row.getNotificationViewWrapper().getNotificationHeader());
sanitizeTopLine(row.getNotificationViewWrapper().getNotificationHeader());
return;
}
final NotificationContentView layout = row.getPrivateLayout();
@@ -171,13 +169,11 @@ public class NotificationHeaderUtil {
private void sanitizeChild(View child) {
if (child != null) {
ViewGroup header = child.findViewById(
com.android.internal.R.id.notification_top_line);
sanitizeHeader(header);
sanitizeTopLine(child.findViewById(R.id.notification_top_line));
}
}
private void sanitizeHeader(ViewGroup rowHeader) {
private void sanitizeTopLine(ViewGroup rowHeader) {
if (rowHeader == null) {
return;
}
@@ -225,28 +221,31 @@ public class NotificationHeaderUtil {
}
}
public void restoreNotificationHeader(ExpandableNotificationRow row) {
for (int compI = 0; compI < mComparators.size(); compI++) {
mComparators.get(compI).apply(row, true /* reset */);
/**
* Reset the modifications to this row for removing it from the group.
*/
public void restoreChildNotification(ExpandableNotificationRow row) {
for (int compI = 0; compI < mProcessors.size(); compI++) {
mProcessors.get(compI).apply(row, true /* reset */);
}
sanitizeHeaderViews(row);
sanitizeTopLineViews(row);
}
private static class HeaderProcessor {
private static class Processor {
private final int mId;
private final DataExtractor mExtractor;
private final ViewComparator mComparator;
private final ResultApplicator mApplicator;
private final ExpandableNotificationRow mParentRow;
private boolean mApply;
private View mParentView;
private ViewComparator mComparator;
private Object mParentData;
public static HeaderProcessor forTextView(ExpandableNotificationRow row, int id) {
return new HeaderProcessor(row, id, null, sTextViewComparator, sVisibilityApplicator);
public static Processor forTextView(ExpandableNotificationRow row, int id) {
return new Processor(row, id, null, TEXT_VIEW_COMPARATOR, VISIBILITY_APPLICATOR);
}
HeaderProcessor(ExpandableNotificationRow row, int id, DataExtractor extractor,
Processor(ExpandableNotificationRow row, int id, DataExtractor extractor,
ViewComparator comparator,
ResultApplicator applicator) {
mId = id;
@@ -262,7 +261,7 @@ public class NotificationHeaderUtil {
mParentData = mExtractor == null ? null : mExtractor.extractData(mParentRow);
mApply = !mComparator.isEmpty(mParentView);
}
public void compareToHeader(ExpandableNotificationRow row) {
public void compareToGroupParent(ExpandableNotificationRow row) {
if (!mApply) {
return;
}
@@ -308,8 +307,8 @@ public class NotificationHeaderUtil {
private interface ViewComparator {
/**
* @param parent the parent view
* @param child the child view
* @param parent the view with the given id in the group header
* @param child the view with the given id in the child notification
* @param parentData optional data for the parent
* @param childData optional data for the child
* @return whether to views are the same
@@ -322,6 +321,21 @@ public class NotificationHeaderUtil {
Object extractData(ExpandableNotificationRow row);
}
private static class BadgeComparator implements ViewComparator {
@Override
public boolean compare(View parent, View child, Object parentData, Object childData) {
return parent.getVisibility() != View.GONE;
}
@Override
public boolean isEmpty(View view) {
if (view instanceof ImageView) {
return ((ImageView) view).getDrawable() == null;
}
return false;
}
}
private static class TextViewComparator implements ViewComparator {
@Override
public boolean compare(View parent, View child, Object parentData, Object childData) {
@@ -338,7 +352,7 @@ public class NotificationHeaderUtil {
}
}
private static abstract class IconComparator implements ViewComparator {
private abstract static class IconComparator implements ViewComparator {
@Override
public boolean compare(View parent, View child, Object parentData, Object childData) {
return false;
@@ -366,6 +380,12 @@ public class NotificationHeaderUtil {
}
private interface ResultApplicator {
/**
* @param parent the root view of the child notification
* @param view the view with the given id in the child notification
* @param apply whether the state should be applied or removed
* @param reset if [de]application is the result of a reset
*/
void apply(View parent, View view, boolean apply, boolean reset);
}
@@ -403,4 +423,54 @@ public class NotificationHeaderUtil {
return super.compare(parent, child, parentData, childData);
}
}
private static class LeftIconApplicator implements ResultApplicator {
public static final int[] MARGIN_ADJUSTED_VIEWS = {
R.id.notification_headerless_view_column,
R.id.line1,
R.id.notification_main_column,
R.id.notification_header};
@Override
public void apply(View parent, View child, boolean apply, boolean reset) {
ImageView rightIcon = child.findViewById(com.android.internal.R.id.right_icon);
ImageView leftIcon = child.findViewById(com.android.internal.R.id.left_icon);
if (rightIcon == null || leftIcon == null) {
return;
}
Drawable iconDrawable = rightIcon.getDrawable();
if (iconDrawable == null) {
return;
}
rightIcon.setVisibility(apply ? View.GONE : View.VISIBLE);
leftIcon.setVisibility(apply ? View.VISIBLE : View.GONE);
leftIcon.setImageDrawable(apply ? iconDrawable : null);
for (int viewId : MARGIN_ADJUSTED_VIEWS) {
adjustMargins(!apply, child.findViewById(viewId));
}
}
void adjustMargins(boolean iconVisible, View target) {
if (target == null) {
return;
}
Integer value = (Integer) target.getTag(iconVisible
? com.android.internal.R.id.tag_margin_end_when_icon_visible
: com.android.internal.R.id.tag_margin_end_when_icon_gone);
if (value == null) {
return;
}
if (target instanceof NotificationHeaderView) {
((NotificationHeaderView) target).setTopLineExtraMarginEnd(value);
} else {
ViewGroup.LayoutParams layoutParams = target.getLayoutParams();
if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(value);
target.setLayoutParams(layoutParams);
}
}
}
}
}

View File

@@ -558,7 +558,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
setChronometerRunning(true);
}
if (mNotificationParent != null) {
mNotificationParent.updateChildrenHeaderAppearance();
mNotificationParent.updateChildrenAppearance();
}
onAttachedChildrenCountChanged();
// The public layouts expand button is always visible
@@ -2337,7 +2337,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
getShowingLayout().updateBackgroundColor(false /* animate */);
mPrivateLayout.updateExpandButtons(isExpandable());
updateChildrenHeaderAppearance();
updateChildrenAppearance();
updateChildrenVisibility();
applyChildrenRoundness();
}
@@ -2382,9 +2382,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return channels;
}
public void updateChildrenHeaderAppearance() {
/**
* If this is a group, update the appearance of the children.
*/
public void updateChildrenAppearance() {
if (mIsSummaryWithChildren) {
mChildrenContainer.updateChildrenHeaderAppearance();
mChildrenContainer.updateChildrenAppearance();
}
}

View File

@@ -64,6 +64,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
private ImageView mWorkProfileImage;
private View mAudiblyAlertedIcon;
private View mFeedbackIcon;
private View mLeftIcon;
private View mRightIcon;
private boolean mIsLowPriority;
@@ -108,6 +109,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
mAppNameText = mView.findViewById(com.android.internal.R.id.app_name_text);
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
mAltExpandTarget = mView.findViewById(com.android.internal.R.id.alternate_expand_target);
mLeftIcon = mView.findViewById(com.android.internal.R.id.left_icon);
mRightIcon = mView.findViewById(com.android.internal.R.id.right_icon);
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
@@ -146,6 +148,9 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
updateCropToPaddingForImageViews();
Notification notification = row.getEntry().getSbn().getNotification();
mIcon.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon());
if (mLeftIcon != null) {
mLeftIcon.setClipToOutline(true);
}
if (mRightIcon != null) {
mRightIcon.setClipToOutline(true);
}

View File

@@ -34,7 +34,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.CachingIconView;
import com.android.systemui.R;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.NotificationHeaderUtil;
import com.android.systemui.statusbar.NotificationGroupingUtil;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -94,7 +94,7 @@ public class NotificationChildrenContainer extends ViewGroup {
private NotificationViewWrapper mNotificationHeaderWrapper;
private NotificationHeaderView mNotificationHeaderLowPriority;
private NotificationViewWrapper mNotificationHeaderWrapperLowPriority;
private NotificationHeaderUtil mHeaderUtil;
private NotificationGroupingUtil mGroupingUtil;
private ViewState mHeaderViewState;
private int mClipBottomAmount;
private boolean mIsLowPriority;
@@ -299,7 +299,7 @@ public class NotificationChildrenContainer extends ViewGroup {
row.setSystemChildExpanded(false);
row.setUserLocked(false);
if (!row.isRemoved()) {
mHeaderUtil.restoreNotificationHeader(row);
mGroupingUtil.restoreChildNotification(row);
}
}
@@ -341,7 +341,7 @@ public class NotificationChildrenContainer extends ViewGroup {
}
recreateLowPriorityHeader(builder, isConversation);
updateHeaderVisibility(false /* animate */);
updateChildrenHeaderAppearance();
updateChildrenAppearance();
}
/**
@@ -389,8 +389,11 @@ public class NotificationChildrenContainer extends ViewGroup {
}
}
public void updateChildrenHeaderAppearance() {
mHeaderUtil.updateChildrenHeaderAppearance();
/**
* Update the appearance of the children to reduce redundancies.
*/
public void updateChildrenAppearance() {
mGroupingUtil.updateChildrenAppearance();
}
public void updateGroupOverflow() {
@@ -861,7 +864,7 @@ public class NotificationChildrenContainer extends ViewGroup {
public void setContainingNotification(ExpandableNotificationRow parent) {
mContainingNotification = parent;
mHeaderUtil = new NotificationHeaderUtil(mContainingNotification);
mGroupingUtil = new NotificationGroupingUtil(mContainingNotification);
}
public ExpandableNotificationRow getContainingNotification() {