diff --git a/quickstep/res/layout/icon_app_chip_view.xml b/quickstep/res/layout/icon_app_chip_view.xml
index 09fb5094fe..3173528248 100644
--- a/quickstep/res/layout/icon_app_chip_view.xml
+++ b/quickstep/res/layout/icon_app_chip_view.xml
@@ -51,25 +51,18 @@
android:importantForAccessibility="no" />
-
-
=
MultiPropertyFactory(this, VIEW_TRANSLATE_Y, INDEX_COUNT_TRANSLATION, SUM_AGGREGATOR)
- var maxWidth = Int.MAX_VALUE
+ // Width showing only the app icon and arrow. Max width should not be set to less than
+ // this.
+ private val minWidthAllowed = iconViewMarginStart + appIconSize + arrowSize + arrowMarginEnd
+ var maxWidth = Integer.MAX_VALUE
/**
* Sets the maximum width of this Icon Menu. This is usually used when space is limited for
* split screen.
@@ -118,8 +125,7 @@ constructor(
set(value) {
// Width showing only the app icon and arrow. Max width should not be set to less than
// this.
- val minMaxWidth = iconViewMarginStart + appIconSize + arrowSize + arrowMarginEnd
- field = max(value, minMaxWidth)
+ field = max(value, minWidthAllowed)
}
var status: AppChipStatus = AppChipStatus.Collapsed
@@ -128,15 +134,14 @@ constructor(
override fun onFinishInflate() {
super.onFinishInflate()
iconView = findViewById(R.id.icon_view)
- iconTextCollapsedView = findViewById(R.id.icon_text_collapsed)
- iconTextExpandedView = findViewById(R.id.icon_text_expanded)
+ appTitle = findViewById(R.id.icon_title)
iconArrowView = findViewById(R.id.icon_arrow)
menuAnchorView = findViewById(R.id.icon_view_menu_anchor)
}
override fun setText(text: CharSequence?) {
- iconTextCollapsedView?.text = text
- iconTextExpandedView?.text = text
+ if (text == appTitle?.text) return
+ appTitle?.text = text
}
override fun getDrawable(): Drawable? = iconView?.drawable
@@ -200,30 +205,17 @@ constructor(
// Layout Params for the collapsed Icon Text View
val textMarginStart =
iconMarginStartRelativeToParent + appIconSize + appNameHorizontalMargin
- val iconTextCollapsedParams = iconTextCollapsedView!!.layoutParams as LayoutParams
+ val iconTextCollapsedParams = appTitle!!.layoutParams as LayoutParams
orientationHandler.setIconAppChipChildrenParams(iconTextCollapsedParams, textMarginStart)
- val collapsedTextWidth =
- (collapsedBackgroundBounds.width() -
- iconViewMarginStart -
- appIconSize -
- arrowSize -
- appNameHorizontalMargin -
- arrowMarginEnd)
- iconTextCollapsedParams.width = collapsedTextWidth
- iconTextCollapsedView!!.layoutParams = iconTextCollapsedParams
- iconTextCollapsedView!!.alpha = 1f
-
- // Layout Params for the expanded Icon Text View
- val iconTextExpandedParams = iconTextExpandedView!!.layoutParams as LayoutParams
- orientationHandler.setIconAppChipChildrenParams(iconTextExpandedParams, textMarginStart)
- iconTextExpandedView!!.layoutParams = iconTextExpandedParams
- iconTextExpandedView!!.alpha = 0f
- iconTextExpandedView!!.setRevealClip(
- true,
- 0f,
- appIconSize / 2f,
- collapsedTextWidth.toFloat(),
- )
+ iconTextCollapsedParams.width =
+ calculateCollapsedTextWidth(collapsedBackgroundBounds.width())
+ appTitle!!.layoutParams = iconTextCollapsedParams
+ // select to enable marquee and disable it when is running test harness.
+ if (Utilities.isRunningInTestHarness()) {
+ disableAppTitleMarquee()
+ } else {
+ appTitle!!.isSelected = true
+ }
// Layout Params for the Icon Arrow View
val iconArrowParams = iconArrowView!!.layoutParams as LayoutParams
@@ -243,6 +235,38 @@ constructor(
)
}
+ private fun disableAppTitleMarquee() {
+ appTitle?.let {
+ it.isHorizontalFadingEdgeEnabled = false
+ it.ellipsize = TextUtils.TruncateAt.END
+ it.horizontallyScrolling = false
+ it.isSelected = false
+ }
+ }
+
+ /**
+ * Calculates the width available for the collapsed text (app name) within the view.
+ *
+ * This function determines the maximum width that the app name can occupy when the view is in
+ * its collapsed state. It considers various factors such as the maximum allowed width, the
+ * bounds of the collapsed background, the size of the app icon, the arrow, and the margins
+ * around these elements.
+ *
+ * @return The calculated width available for the collapsed text (app name).
+ */
+ private fun calculateCollapsedTextWidth(width: Int): Int {
+ val collapsedTextWidth =
+ (width -
+ iconViewMarginStart -
+ appIconSize -
+ arrowSize -
+ appNameHorizontalMargin -
+ arrowMarginEnd)
+
+ val spaceLeftForText = maxWidth - minWidthAllowed
+ return minOf(collapsedTextWidth, spaceLeftForText)
+ }
+
override fun setIconColorTint(color: Int, amount: Float) {
// RecentsView's COLOR_TINT animates between 0 and 0.5f, we want to hide the app chip menu.
val colorTintAlpha = Utilities.mapToRange(amount, 0f, 0.5f, 1f, 0f, Interpolators.LINEAR)
@@ -312,11 +336,11 @@ constructor(
// Clip expanded text with reveal animation so it doesn't go beyond the edge of the menu
val expandedTextRevealAnim =
ViewAnimationUtils.createCircularReveal(
- iconTextExpandedView,
+ appTitle,
0,
- iconTextExpandedView!!.height / 2,
- iconTextCollapsedView!!.width.toFloat(),
- iconTextExpandedView!!.width.toFloat(),
+ appTitle!!.height / 2,
+ appTitle!!.width.toFloat(),
+ expandedMaxTextWidth.toFloat(),
)
// Animate background clipping
val backgroundAnimator =
@@ -343,18 +367,7 @@ constructor(
backgroundAnimator,
ObjectAnimator.ofFloat(iconView, SCALE_X, iconViewScaling),
ObjectAnimator.ofFloat(iconView, SCALE_Y, iconViewScaling),
- ObjectAnimator.ofFloat(
- iconTextCollapsedView,
- TRANSLATION_X,
- textTranslationXWithRtl,
- ),
- ObjectAnimator.ofFloat(
- iconTextExpandedView,
- TRANSLATION_X,
- textTranslationXWithRtl,
- ),
- ObjectAnimator.ofFloat(iconTextCollapsedView, ALPHA, 0f),
- ObjectAnimator.ofFloat(iconTextExpandedView, ALPHA, 1f),
+ ObjectAnimator.ofFloat(appTitle, TRANSLATION_X, textTranslationXWithRtl),
ObjectAnimator.ofFloat(iconArrowView, TRANSLATION_X, arrowTranslationWithRtl),
ObjectAnimator.ofFloat(iconArrowView, SCALE_Y, -1f),
)
@@ -364,11 +377,11 @@ constructor(
// Clip expanded text with reveal animation so it doesn't go beyond the edge of the menu
val expandedTextClipAnim =
ViewAnimationUtils.createCircularReveal(
- iconTextExpandedView,
+ appTitle,
0,
- iconTextExpandedView!!.height / 2,
- iconTextExpandedView!!.width.toFloat(),
- iconTextCollapsedView!!.width.toFloat(),
+ appTitle!!.height / 2,
+ appTitle!!.width.toFloat(),
+ calculateCollapsedTextWidth(collapsedBackgroundBounds.width()).toFloat(),
)
// Animate background clipping
@@ -386,10 +399,7 @@ constructor(
expandedTextClipAnim,
backgroundAnimator,
ObjectAnimator.ofFloat(iconView, SCALE_PROPERTY, 1f),
- ObjectAnimator.ofFloat(iconTextCollapsedView, TRANSLATION_X, 0f),
- ObjectAnimator.ofFloat(iconTextExpandedView, TRANSLATION_X, 0f),
- ObjectAnimator.ofFloat(iconTextCollapsedView, ALPHA, 1f),
- ObjectAnimator.ofFloat(iconTextExpandedView, ALPHA, 0f),
+ ObjectAnimator.ofFloat(appTitle, TRANSLATION_X, 0f),
ObjectAnimator.ofFloat(iconArrowView, TRANSLATION_X, 0f),
ObjectAnimator.ofFloat(iconArrowView, SCALE_Y, 1f),
)
@@ -399,9 +409,45 @@ constructor(
if (!animated) animator!!.duration = 0
animator!!.interpolator = Interpolators.EMPHASIZED
+ animator!!.addListener(
+ onStart = {
+ appTitle!!.isSelected = false
+ if (status == AppChipStatus.Expanded) updateTitleSize()
+ },
+ onEnd = {
+ if (status == AppChipStatus.Collapsed) updateTitleSize()
+ appTitle!!.isSelected = true
+ },
+ )
+
animator!!.start()
}
+ /**
+ * Updates the width of the app title based on the current [AppChipStatus].
+ *
+ * This function dynamically adjusts the width of the `appTitle` TextView depending on whether
+ * the app chip is in an expanded or collapsed state.
+ * - When the chip is [AppChipStatus.Expanded], the title width is set to
+ * [expandedMaxTextWidth], allowing the title to potentially take up more space.
+ * - When the chip is [AppChipStatus.Collapsed], the title width is calculated based on the
+ * width of the collapsed background. This ensures the title fits within the smaller,
+ * collapsed chip boundaries. The width is then determined by calling
+ * [calculateCollapsedTextWidth].
+ */
+ private fun updateTitleSize() {
+ val appTitleWidth =
+ when (status) {
+ AppChipStatus.Expanded -> expandedMaxTextWidth
+ AppChipStatus.Collapsed -> {
+ val collapsedBackgroundWidth = getCollapsedBackgroundLtrBounds().width()
+ calculateCollapsedTextWidth(collapsedBackgroundWidth)
+ }
+ }
+
+ appTitle!!.updateLayoutParams { width = appTitleWidth }
+ }
+
private fun getCollapsedBackgroundLtrBounds(): Rect {
val bounds =
Rect(0, 0, min(maxWidth, collapsedMenuDefaultWidth), collapsedMenuDefaultHeight)