From f33f1daf62ef743c93ab49a020bf609a10895e19 Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Tue, 14 Dec 2021 14:10:20 -0800 Subject: [PATCH] Use ConstraintLayout for BadgedImageView App icon badge size is based on the view size, as a ratio. Use ConstraintLayout to define the app icon size based on constraints. This way we do not have to recalculate the app icon size manually. If the BadgedImageView size changes, app icon will be resized automatically. App icon badge position is fixed to the right. If it needs to be shown on the left, due to bubble position, we update the location using translationX. Bug: 162857077 Test: verified visually that bubble with app icon looks the same Test: verified visually that when display size changes, app icon changes together with bubble size Test: ran WMShellUnitTests unit tests Change-Id: I63a6cadfc7847dd0c0d9dca6bb6efd11f5b9958e --- libs/WindowManager/Shell/Android.bp | 30 +++++----- .../Shell/res/layout/badged_image_view.xml | 55 +++++++++++++++++++ .../wm/shell/bubbles/BadgedImageView.java | 41 ++++++-------- 3 files changed, 88 insertions(+), 38 deletions(-) create mode 100644 libs/WindowManager/Shell/res/layout/badged_image_view.xml diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index cdff5858c77db..e9b3c4990ef2e 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -43,7 +43,7 @@ filegroup { name: "wm_shell_util-sources", srcs: [ "src/com/android/wm/shell/util/**/*.java", - "src/com/android/wm/shell/common/split/SplitScreenConstants.java" + "src/com/android/wm/shell/common/split/SplitScreenConstants.java", ], path: "src", } @@ -74,13 +74,13 @@ genrule { ], tools: ["protologtool"], cmd: "$(location protologtool) transform-protolog-calls " + - "--protolog-class com.android.internal.protolog.common.ProtoLog " + - "--protolog-impl-class com.android.wm.shell.protolog.ShellProtoLogImpl " + - "--protolog-cache-class com.android.wm.shell.protolog.ShellProtoLogCache " + - "--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " + - "--loggroups-jar $(location :wm_shell_protolog-groups) " + - "--output-srcjar $(out) " + - "$(locations :wm_shell-sources)", + "--protolog-class com.android.internal.protolog.common.ProtoLog " + + "--protolog-impl-class com.android.wm.shell.protolog.ShellProtoLogImpl " + + "--protolog-cache-class com.android.wm.shell.protolog.ShellProtoLogCache " + + "--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " + + "--loggroups-jar $(location :wm_shell_protolog-groups) " + + "--output-srcjar $(out) " + + "$(locations :wm_shell-sources)", out: ["wm_shell_protolog.srcjar"], } @@ -92,13 +92,14 @@ genrule { ], tools: ["protologtool"], cmd: "$(location protologtool) generate-viewer-config " + - "--protolog-class com.android.internal.protolog.common.ProtoLog " + - "--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " + - "--loggroups-jar $(location :wm_shell_protolog-groups) " + - "--viewer-conf $(out) " + - "$(locations :wm_shell-sources)", + "--protolog-class com.android.internal.protolog.common.ProtoLog " + + "--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " + + "--loggroups-jar $(location :wm_shell_protolog-groups) " + + "--viewer-conf $(out) " + + "$(locations :wm_shell-sources)", out: ["wm_shell_protolog.json"], } + // End ProtoLog java_library { @@ -123,11 +124,12 @@ android_library { "res", ], java_resources: [ - ":generate-wm_shell_protolog.json" + ":generate-wm_shell_protolog.json", ], static_libs: [ "androidx.appcompat_appcompat", "androidx.arch.core_core-runtime", + "androidx-constraintlayout_constraintlayout", "androidx.dynamicanimation_dynamicanimation", "androidx.recyclerview_recyclerview", "kotlinx-coroutines-android", diff --git a/libs/WindowManager/Shell/res/layout/badged_image_view.xml b/libs/WindowManager/Shell/res/layout/badged_image_view.xml new file mode 100644 index 0000000000000..5f07121ec7d39 --- /dev/null +++ b/libs/WindowManager/Shell/res/layout/badged_image_view.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java index 686fbbfd6f7cd..c52d87dde07f3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java @@ -19,7 +19,6 @@ import android.annotation.DrawableRes; import android.annotation.Nullable; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Outline; import android.graphics.Path; @@ -27,14 +26,16 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.PathParser; -import android.view.Gravity; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewOutlineProvider; -import android.widget.FrameLayout; import android.widget.ImageView; +import androidx.constraintlayout.widget.ConstraintLayout; + import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.icons.IconNormalizer; +import com.android.wm.shell.R; import com.android.wm.shell.animation.Interpolators; import java.util.EnumSet; @@ -46,14 +47,12 @@ import java.util.EnumSet; * Badge = the icon associated with the app that created this bubble, this will show work profile * badge if appropriate. */ -public class BadgedImageView extends FrameLayout { +public class BadgedImageView extends ConstraintLayout { /** Same value as Launcher3 dot code */ public static final float WHITE_SCRIM_ALPHA = 0.54f; /** Same as value in Launcher3 IconShape */ public static final int DEFAULT_PATH_SIZE = 100; - /** Same as value in Launcher3 BaseIconFactory */ - private static final float ICON_BADGE_SCALE = 0.444f; /** * Flags that suppress the visibility of the 'new' dot, for one reason or another. If any of @@ -105,11 +104,13 @@ public class BadgedImageView extends FrameLayout { public BadgedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + // We manage positioning the badge ourselves + setLayoutDirection(LAYOUT_DIRECTION_LTR); - mBubbleIcon = new ImageView(context); - addView(mBubbleIcon); - mAppIcon = new ImageView(context); - addView(mAppIcon); + LayoutInflater.from(context).inflate(R.layout.badged_image_view, this); + + mBubbleIcon = findViewById(R.id.icon_view); + mAppIcon = findViewById(R.id.app_icon_view); final TypedArray ta = mContext.obtainStyledAttributes(attrs, new int[]{android.R.attr.src}, defStyleAttr, defStyleRes); @@ -161,6 +162,7 @@ public class BadgedImageView extends FrameLayout { public void setRenderedBubble(BubbleViewProvider bubble) { mBubble = bubble; mBubbleIcon.setImageBitmap(bubble.getBubbleIcon()); + mAppIcon.setImageBitmap(bubble.getAppBadge()); if (mDotSuppressionFlags.contains(SuppressionFlag.BEHIND_STACK)) { hideBadge(); } else { @@ -348,26 +350,17 @@ public class BadgedImageView extends FrameLayout { } void showBadge() { - Bitmap badge = mBubble.getAppBadge(); - if (badge == null) { + if (mBubble.getAppBadge() == null) { mAppIcon.setVisibility(GONE); return; } - - final int bubbleSize = mBubble.getBubbleIcon().getWidth(); - final int badgeSize = (int) (ICON_BADGE_SCALE * bubbleSize); - - FrameLayout.LayoutParams appIconParams = (LayoutParams) mAppIcon.getLayoutParams(); - appIconParams.height = badgeSize; - appIconParams.width = badgeSize; + int translationX; if (mOnLeft) { - appIconParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + translationX = -(mBubbleIcon.getWidth() - mAppIcon.getWidth()); } else { - appIconParams.gravity = Gravity.BOTTOM | Gravity.RIGHT; + translationX = 0; } - mAppIcon.setLayoutParams(appIconParams); - - mAppIcon.setImageBitmap(badge); + mAppIcon.setTranslationX(translationX); mAppIcon.setVisibility(VISIBLE); }