Merge "Fix RTL text in TransitionLayout" into rvc-dev am: 2b33bad9c2

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12018133

Change-Id: Ifbcae444e5bb73e7678f10740bfc77b8bc758afa
This commit is contained in:
Selim Cinek
2020-06-29 07:44:44 +00:00
committed by Automerger Merge Worker
4 changed files with 42 additions and 46 deletions

View File

@@ -65,25 +65,16 @@
<!-- Actions must be ordered left-to-right even in RTL layout. However, they appear in a chain <!-- Actions must be ordered left-to-right even in RTL layout. However, they appear in a chain
with the album art and the title, and must as a group appear at the end of that chain. This is with the album art and the title, and must as a group appear at the end of that chain. This is
accomplished by having the guidebox (an invisible view that is positioned around all 5 actions) accomplished by having all actions appear in a LTR chain within the parent, and then biasing it
in the chain with the album art and the title. The actions are in a LTR chain bounded by that to the right side, then this barrier is used to bound the text views. -->
guidebox, and the ambiguity of how wide the guidebox should be is resolved by using a barrier
which forces it's starting edge to be as far to the end as possible while fitting the actions.
-->
<androidx.constraintlayout.widget.Barrier <androidx.constraintlayout.widget.Barrier
android:id="@+id/media_action_barrier" android:id="@+id/media_action_barrier"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:barrierDirection="start" app:barrierDirection="start"
/> app:constraint_referenced_ids="action0,action1,action2,action3,action4"
<View
android:id="@+id/media_action_guidebox"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginTop="16dp"
android:visibility="invisible"
/> />
<ImageButton <ImageButton
@@ -201,7 +192,6 @@
android:fontFamily="@*android:string/config_headlineFontFamilyMedium" android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
android:singleLine="true" android:singleLine="true"
android:textColor="@color/media_primary_text" android:textColor="@color/media_primary_text"
android:textDirection="locale"
android:textSize="16sp" /> android:textSize="16sp" />
<!-- Artist name --> <!-- Artist name -->
@@ -212,7 +202,6 @@
android:fontFamily="@*android:string/config_headlineFontFamily" android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true" android:singleLine="true"
android:textColor="@color/media_secondary_text" android:textColor="@color/media_secondary_text"
android:textDirection="locale"
android:textSize="14sp" /> android:textSize="14sp" />
<com.android.internal.widget.CachingIconView <com.android.internal.widget.CachingIconView

View File

@@ -85,10 +85,11 @@
<!-- Song name --> <!-- Song name -->
<Constraint <Constraint
android:id="@+id/header_title" android:id="@+id/header_title"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="17dp" android:layout_marginTop="17dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="@id/app_name" app:layout_constraintTop_toBottomOf="@id/app_name"
app:layout_constraintBottom_toTopOf="@id/header_artist" app:layout_constraintBottom_toTopOf="@id/header_artist"
app:layout_constraintStart_toEndOf="@id/album_art" app:layout_constraintStart_toEndOf="@id/album_art"
@@ -98,10 +99,11 @@
<!-- Artist name --> <!-- Artist name -->
<Constraint <Constraint
android:id="@+id/header_artist" android:id="@+id/header_artist"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="3dp" android:layout_marginTop="3dp"
android:layout_marginBottom="24dp" android:layout_marginBottom="24dp"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="@id/header_title" app:layout_constraintTop_toBottomOf="@id/header_title"
app:layout_constraintStart_toStartOf="@id/header_title" app:layout_constraintStart_toStartOf="@id/header_title"
app:layout_constraintEnd_toStartOf="@id/media_action_barrier" app:layout_constraintEnd_toStartOf="@id/media_action_barrier"
@@ -134,27 +136,6 @@
android:visibility="gone" android:visibility="gone"
/> />
<Constraint
android:id="@+id/media_action_barrier"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:barrierDirection="start"
app:constraint_referenced_ids="media_action_guidebox,action0,action1,action2,action3,action4"
/>
<Constraint
android:id="@+id/media_action_guidebox"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginTop="18dp"
android:visibility="invisible"
app:layout_constraintTop_toBottomOf="@id/app_name"
app:layout_constraintStart_toEndOf="@id/header_title"
app:layout_constraintEnd_toEndOf="parent"
/>
<Constraint <Constraint
android:id="@+id/action0" android:id="@+id/action0"
android:layout_width="48dp" android:layout_width="48dp"
@@ -165,8 +146,9 @@
android:visibility="gone" android:visibility="gone"
app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintTop_toBottomOf="@id/app_name" app:layout_constraintTop_toBottomOf="@id/app_name"
app:layout_constraintLeft_toLeftOf="@id/media_action_guidebox" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/action1" app:layout_constraintRight_toLeftOf="@id/action1"
app:layout_constraintHorizontal_bias="1"
> >
</Constraint> </Constraint>
@@ -220,7 +202,8 @@
app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintTop_toBottomOf="@id/app_name" app:layout_constraintTop_toBottomOf="@id/app_name"
app:layout_constraintLeft_toRightOf="@id/action3" app:layout_constraintLeft_toRightOf="@id/action3"
app:layout_constraintRight_toRightOf="@id/media_action_guidebox" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0"
> >
</Constraint> </Constraint>
</ConstraintSet> </ConstraintSet>

View File

@@ -83,11 +83,12 @@
<!-- Song name --> <!-- Song name -->
<Constraint <Constraint
android:id="@+id/header_title" android:id="@+id/header_title"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/qs_media_panel_outer_padding" android:layout_marginEnd="@dimen/qs_media_panel_outer_padding"
android:layout_marginTop="17dp" android:layout_marginTop="17dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="@+id/app_name" app:layout_constraintTop_toBottomOf="@+id/app_name"
app:layout_constraintStart_toEndOf="@id/album_art" app:layout_constraintStart_toEndOf="@id/album_art"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@@ -96,10 +97,11 @@
<!-- Artist name --> <!-- Artist name -->
<Constraint <Constraint
android:id="@+id/header_artist" android:id="@+id/header_artist"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/qs_media_panel_outer_padding" android:layout_marginEnd="@dimen/qs_media_panel_outer_padding"
android:layout_marginTop="3dp" android:layout_marginTop="3dp"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="@id/header_title" app:layout_constraintTop_toBottomOf="@id/header_title"
app:layout_constraintStart_toStartOf="@id/header_title" app:layout_constraintStart_toStartOf="@id/header_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

View File

@@ -20,9 +20,11 @@ import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.PointF import android.graphics.PointF
import android.graphics.Rect import android.graphics.Rect
import android.text.Layout
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet
import com.android.systemui.statusbar.CrossFadeHelper import com.android.systemui.statusbar.CrossFadeHelper
@@ -85,6 +87,23 @@ class TransitionLayout @JvmOverloads constructor(
for (i in 0 until childCount) { for (i in 0 until childCount) {
val child = getChildAt(i) val child = getChildAt(i)
val widgetState = currentState.widgetStates.get(child.id) ?: continue val widgetState = currentState.widgetStates.get(child.id) ?: continue
// TextViews which are measured and sized differently should be handled with a
// "clip mode", which means we clip explicitly rather than implicitly by passing
// different sizes to measure/layout than setLeftTopRightBottom.
// Then to accommodate RTL text, we need a "clip shift" which allows us to have the
// clipBounds be attached to the right side of the view instead of the left.
val clipModeShift =
if (child is TextView && widgetState.width < widgetState.measureWidth) {
if (child.layout.getParagraphDirection(0) == Layout.DIR_RIGHT_TO_LEFT) {
widgetState.measureWidth - widgetState.width
} else {
0
}
} else {
null
}
if (child.measuredWidth != widgetState.measureWidth || if (child.measuredWidth != widgetState.measureWidth ||
child.measuredHeight != widgetState.measureHeight) { child.measuredHeight != widgetState.measureHeight) {
val measureWidthSpec = MeasureSpec.makeMeasureSpec(widgetState.measureWidth, val measureWidthSpec = MeasureSpec.makeMeasureSpec(widgetState.measureWidth,
@@ -94,14 +113,17 @@ class TransitionLayout @JvmOverloads constructor(
child.measure(measureWidthSpec, measureHeightSpec) child.measure(measureWidthSpec, measureHeightSpec)
child.layout(0, 0, child.measuredWidth, child.measuredHeight) child.layout(0, 0, child.measuredWidth, child.measuredHeight)
} }
val left = widgetState.x.toInt() + contentTranslationX val clipShift = clipModeShift ?: 0
val left = widgetState.x.toInt() + contentTranslationX - clipShift
val top = widgetState.y.toInt() + contentTranslationY val top = widgetState.y.toInt() + contentTranslationY
child.setLeftTopRightBottom(left, top, left + widgetState.width, val clipMode = clipModeShift != null
top + widgetState.height) val boundsWidth = if (clipMode) widgetState.measureWidth else widgetState.width
val boundsHeight = if (clipMode) widgetState.measureHeight else widgetState.height
child.setLeftTopRightBottom(left, top, left + boundsWidth, top + boundsHeight)
child.scaleX = widgetState.scale child.scaleX = widgetState.scale
child.scaleY = widgetState.scale child.scaleY = widgetState.scale
val clipBounds = child.clipBounds ?: Rect() val clipBounds = child.clipBounds ?: Rect()
clipBounds.set(0, 0, widgetState.width, widgetState.height) clipBounds.set(clipShift, 0, widgetState.width + clipShift, widgetState.height)
child.clipBounds = clipBounds child.clipBounds = clipBounds
CrossFadeHelper.fadeIn(child, widgetState.alpha) CrossFadeHelper.fadeIn(child, widgetState.alpha)
child.visibility = if (widgetState.gone || widgetState.alpha == 0.0f) { child.visibility = if (widgetState.gone || widgetState.alpha == 0.0f) {