Skip to content

Commit

Permalink
[TopAppBar] Fix text alignment of multi-line title in collapsing toolbar
Browse files Browse the repository at this point in the history
In single line mode, we implement the expanded title alignment by calculating the expected x-coordinate of expanded title and translate the canvas so the title will be aligned. However, when maxLines > 1, the static layout will always occupy the full available width, therefore the text alignment need to be done by the static layout instead.

Provides text alignment other than NORMAL when it's in multi-line mode to solve the issue.

Resolves #1276

PiperOrigin-RevId: 408895140
  • Loading branch information
drchen committed Nov 10, 2021
1 parent 823c34a commit e6db8a4
Showing 1 changed file with 22 additions and 2 deletions.
Expand Up @@ -17,7 +17,9 @@
package com.google.android.material.internal;

import static androidx.core.util.Preconditions.checkNotNull;
import static android.text.Layout.Alignment.ALIGN_CENTER;
import static android.text.Layout.Alignment.ALIGN_NORMAL;
import static android.text.Layout.Alignment.ALIGN_OPPOSITE;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import static java.lang.Math.max;
import static java.lang.Math.min;
Expand All @@ -36,6 +38,7 @@
import android.os.Build.VERSION_CODES;
import androidx.core.view.GravityCompat;
import androidx.core.view.ViewCompat;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
Expand Down Expand Up @@ -820,7 +823,7 @@ private boolean shouldDrawMultiline() {

private void drawMultilineTransition(@NonNull Canvas canvas, float currentExpandedX, float y) {
int originalAlpha = textPaint.getAlpha();
// positon expanded text appropriately
// position expanded text appropriately
canvas.translate(currentExpandedX, y);
// Expanded text
textPaint.setAlpha((int) (expandedTextBlend * originalAlpha));
Expand Down Expand Up @@ -967,11 +970,13 @@ private void calculateUsingTextSize(final float textSize, boolean forceRecalcula
private StaticLayout createStaticLayout(int maxLines, float availableWidth, boolean isRtl) {
StaticLayout textLayout = null;
try {
// In multiline mode, the text alignment should be controlled by the static layout.
Alignment textAlignment = maxLines == 1 ? ALIGN_NORMAL : getMultilineTextLayoutAlignment();
textLayout =
StaticLayoutBuilderCompat.obtain(text, textPaint, (int) availableWidth)
.setEllipsize(TruncateAt.END)
.setIsRtl(isRtl)
.setAlignment(ALIGN_NORMAL)
.setAlignment(textAlignment)
.setIncludePad(false)
.setMaxLines(maxLines)
.setLineSpacing(lineSpacingAdd, lineSpacingMultiplier)
Expand All @@ -984,6 +989,21 @@ private StaticLayout createStaticLayout(int maxLines, float availableWidth, bool
return checkNotNull(textLayout);
}

private Alignment getMultilineTextLayoutAlignment() {
int absoluteGravity =
GravityCompat.getAbsoluteGravity(
expandedTextGravity,
isRtl ? ViewCompat.LAYOUT_DIRECTION_RTL : ViewCompat.LAYOUT_DIRECTION_LTR);
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
case Gravity.CENTER_HORIZONTAL:
return ALIGN_CENTER;
case Gravity.RIGHT:
return isRtl ? ALIGN_NORMAL : ALIGN_OPPOSITE;
default:
return isRtl ? ALIGN_OPPOSITE : ALIGN_NORMAL;
}
}

private void ensureExpandedTexture() {
if (expandedTitleTexture != null || expandedBounds.isEmpty() || TextUtils.isEmpty(textToDraw)) {
return;
Expand Down

0 comments on commit e6db8a4

Please sign in to comment.