Update marquee to show only when chip is expanded

- Introduced title and titleCollapsed to change the text when expanded and collapsed using only 2 dots for truncate the text, similar to ellipsize="marquee".

- Removed ellipsize="marquee" from the XML to prevent chip relayout when entering in Overview. See b/406969521.

Fix: 406969521
Fix: 403193877
Flag: com.android.launcher3.enable_overview_icon_menu
Test: OverviewImageTest
Test: OverviewSplitTaskImageTest
Change-Id: Ia95eb8b7ec6d22b9d576defe7c66a4950ee1dca3
This commit is contained in:
Jordan Silva
2025-03-28 18:40:45 +00:00
parent 12a154e1e2
commit 612aac88cb
3 changed files with 52 additions and 31 deletions

View File

@@ -57,10 +57,11 @@
android:gravity="start|center_vertical"
android:maxLines="1"
android:singleLine="true"
android:ellipsize="marquee"
android:ellipsize="none"
android:textAlignment="viewStart"
android:importantForAccessibility="no"
android:fadingEdge="horizontal"
android:requiresFadingEdge="horizontal"
android:fadingEdgeLength="@dimen/task_thumbnail_icon_menu_text_fading_size"
android:marqueeRepeatLimit="1"
android:scrollHorizontally="true"
style="@style/IconAppChipMenuTextStyle" />

View File

@@ -66,6 +66,8 @@
<dimen name="task_thumbnail_icon_menu_background_margin_top_start">8dp</dimen>
<!-- The margin between the app name + app icon and app name + arrow icon when collapsed -->
<dimen name="task_thumbnail_icon_menu_app_name_margin_horizontal_collapsed">8dp</dimen>
<!-- The margin between the app name + app icon and app name + arrow icon when expanded -->
<dimen name="task_thumbnail_icon_menu_app_name_margin_horizontal_expanded">12dp</dimen>
<!-- The gap at the top of the task icon menu when expanded -->
<dimen name="task_thumbnail_icon_menu_expanded_gap">2dp</dimen>
<!-- The margin at the start of the task icon view in the icon menu -->
@@ -81,6 +83,8 @@
<!-- The size of the icon menu's icon touch target -->
<dimen name="task_thumbnail_icon_menu_drawable_touch_size">44dp</dimen>
<dimen name="task_thumbnail_icon_menu_elevation">4dp</dimen>
<!-- The size of the text fading horizontally -->
<dimen name="task_thumbnail_icon_menu_text_fading_size">20dp</dimen>
<!-- The size of the task thumbnail header -->
<dimen name="task_thumbnail_header_height">30dp</dimen>
<dimen name="task_thumbnail_header_margin_edge">18dp</dimen>

View File

@@ -23,7 +23,7 @@ import android.content.Context
import android.graphics.Outline
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.text.TextUtils.TruncateAt
import android.util.AttributeSet
import android.view.View
import android.view.ViewAnimationUtils
@@ -87,10 +87,14 @@ constructor(
)
// Contents dimensions
private val appNameHorizontalMargin =
private val appNameHorizontalMarginCollapsed =
resources.getDimensionPixelSize(
R.dimen.task_thumbnail_icon_menu_app_name_margin_horizontal_collapsed
)
private val appNameHorizontalMarginExpanded =
resources.getDimensionPixelSize(
R.dimen.task_thumbnail_icon_menu_app_name_margin_horizontal_expanded
)
private val arrowMarginEnd =
resources.getDimensionPixelSize(R.dimen.task_thumbnail_icon_menu_arrow_margin)
private val iconViewMarginStart =
@@ -148,6 +152,7 @@ constructor(
override fun getDrawable(): Drawable? = iconView?.drawable
private var currentIconDrawableHash: Int = 0
override fun setDrawable(icon: Drawable?) {
if (icon.hashCode() == currentIconDrawableHash) return
iconView?.drawable = icon
@@ -209,18 +214,12 @@ constructor(
// Layout Params for the collapsed Icon Text View
val textMarginStart =
iconMarginStartRelativeToParent + appIconSize + appNameHorizontalMargin
iconMarginStartRelativeToParent + appIconSize + appNameHorizontalMarginCollapsed
val iconTextCollapsedParams = appTitle!!.layoutParams as LayoutParams
orientationHandler.setIconAppChipChildrenParams(iconTextCollapsedParams, textMarginStart)
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
}
appTitle?.layoutParams = iconTextCollapsedParams
// Layout Params for the Icon Arrow View
val iconArrowParams = iconArrowView!!.layoutParams as LayoutParams
@@ -240,12 +239,12 @@ constructor(
)
}
private fun disableAppTitleMarquee() {
private fun enableMarquee(isEnabled: Boolean) {
// Marquee should not be enabled when is running test harness.
val isMarqueeEnabled = isEnabled && !Utilities.isRunningInTestHarness()
appTitle?.let {
it.isHorizontalFadingEdgeEnabled = false
it.ellipsize = TextUtils.TruncateAt.END
it.horizontallyScrolling = false
it.isSelected = false
it.ellipsize = if (isMarqueeEnabled) TruncateAt.MARQUEE else null
it.isSelected = isMarqueeEnabled
}
}
@@ -265,13 +264,21 @@ constructor(
iconViewMarginStart -
appIconSize -
arrowSize -
appNameHorizontalMargin -
appNameHorizontalMarginCollapsed -
arrowMarginEnd)
val spaceLeftForText = maxWidth - minWidthAllowed
return minOf(collapsedTextWidth, spaceLeftForText)
return minOf(collapsedTextWidth, spaceLeftForText).coerceAtLeast(0)
}
private fun calculateExpandedTextWidth(width: Int): Int =
width -
iconViewMarginStart -
iconViewDrawableExpandedSize -
arrowSize -
appNameHorizontalMarginExpanded -
arrowMarginEnd
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)
@@ -339,13 +346,14 @@ constructor(
val isRtl = isLayoutRtl
bringToFront()
// Clip expanded text with reveal animation so it doesn't go beyond the edge of the menu
val expandedAppTitleWidth = calculateExpandedTextWidth(expandedBackgroundBounds.width())
val expandedTextRevealAnim =
ViewAnimationUtils.createCircularReveal(
appTitle,
0,
appTitle!!.height / 2,
appTitle!!.width.toFloat(),
expandedMaxTextWidth.toFloat(),
expandedAppTitleWidth.toFloat(),
)
// Animate background clipping
val backgroundAnimator =
@@ -359,9 +367,9 @@ constructor(
val iconViewScaling = iconViewDrawableExpandedSize / appIconSize.toFloat()
val arrowTranslationX =
(expandedBackgroundBounds.right - collapsedBackgroundBounds.right).toFloat()
val iconCenterToTextCollapsed = appIconSize / 2f + appNameHorizontalMargin
val iconCenterToTextCollapsed = appIconSize / 2f + appNameHorizontalMarginCollapsed
val iconCenterToTextExpanded =
iconViewDrawableExpandedSize / 2f + appNameHorizontalMargin
iconViewDrawableExpandedSize / 2f + appNameHorizontalMarginCollapsed
val textTranslationX = iconCenterToTextExpanded - iconCenterToTextCollapsed
val textTranslationXWithRtl = if (isRtl) -textTranslationX else textTranslationX
@@ -414,14 +422,23 @@ constructor(
if (!animated) animator!!.duration = 0
animator!!.interpolator = Interpolators.EMPHASIZED
// Increase the chip and appTitle size before the animation starts when it's expanding.
// And decrease the size after the animation when is collapsing.
animator!!.addListener(
onStart = {
appTitle!!.isSelected = false
if (status == AppChipStatus.Expanded) updateChipSize()
when (status) {
AppChipStatus.Expanded -> updateChipSize()
// Disable marquee before chip is collapsed
AppChipStatus.Collapsed -> enableMarquee(false)
}
},
onEnd = {
if (status == AppChipStatus.Collapsed) updateChipSize()
appTitle!!.isSelected = true
when (status) {
AppChipStatus.Collapsed -> updateChipSize()
// Enable marquee after chip is fully expanded
AppChipStatus.Expanded -> enableMarquee(true)
}
},
)
animator!!.start()
@@ -444,7 +461,7 @@ constructor(
when (status) {
AppChipStatus.Expanded -> {
updateLayoutParams { width = chipWidth }
appTitle!!.updateLayoutParams { width = expandedMaxTextWidth }
appTitle!!.updateLayoutParams { width = calculateExpandedTextWidth(chipWidth) }
}
AppChipStatus.Collapsed -> {
appTitle!!.updateLayoutParams {
@@ -491,17 +508,16 @@ constructor(
if (mParent == null) return null
return when (direction) {
FOCUS_RIGHT,
FOCUS_DOWN -> mParent.focusSearch(this, View.FOCUS_FORWARD)
FOCUS_DOWN -> mParent.focusSearch(this, FOCUS_FORWARD)
FOCUS_UP,
FOCUS_LEFT -> mParent.focusSearch(this, View.FOCUS_BACKWARD)
FOCUS_LEFT -> mParent.focusSearch(this, FOCUS_BACKWARD)
else -> super.focusSearch(direction)
}
}
fun reset() {
setText(null)
setDrawable(null)
currentIconDrawableHash = 0
drawable = null
}
override fun asView(): View = this