Merge "StaticLayout visual fix for maxLines"
This commit is contained in:
committed by
Android (Google) Code Review
commit
9aba698bd1
@@ -633,6 +633,17 @@ public abstract class Layout {
|
||||
return getLineTop(getLineCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total height of this layout.
|
||||
*
|
||||
* @param cap if true and max lines is set, returns the height of the layout at the max lines.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public int getHeight(boolean cap) {
|
||||
return getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base alignment of this layout.
|
||||
*/
|
||||
|
||||
@@ -836,7 +836,7 @@ public class StaticLayout extends Layout {
|
||||
here = endPos;
|
||||
breakIndex++;
|
||||
|
||||
if (mLineCount >= mMaximumVisibleLineCount) {
|
||||
if (mLineCount >= mMaximumVisibleLineCount && mEllipsized) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -920,7 +920,25 @@ public class StaticLayout extends Layout {
|
||||
|
||||
boolean firstLine = (j == 0);
|
||||
boolean currentLineIsTheLastVisibleOne = (j + 1 == mMaximumVisibleLineCount);
|
||||
boolean lastLine = currentLineIsTheLastVisibleOne || (end == bufEnd);
|
||||
|
||||
if (ellipsize != null) {
|
||||
// If there is only one line, then do any type of ellipsis except when it is MARQUEE
|
||||
// if there are multiple lines, just allow END ellipsis on the last line
|
||||
boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount);
|
||||
|
||||
boolean doEllipsis =
|
||||
(((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) &&
|
||||
ellipsize != TextUtils.TruncateAt.MARQUEE) ||
|
||||
(!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) &&
|
||||
ellipsize == TextUtils.TruncateAt.END);
|
||||
if (doEllipsis) {
|
||||
calculateEllipsis(start, end, widths, widthStart,
|
||||
ellipsisWidth, ellipsize, j,
|
||||
textWidth, paint, forceEllipsis);
|
||||
}
|
||||
}
|
||||
|
||||
boolean lastLine = mEllipsized || (end == bufEnd);
|
||||
|
||||
if (firstLine) {
|
||||
if (trackPad) {
|
||||
@@ -944,7 +962,6 @@ public class StaticLayout extends Layout {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (needMultiply && !lastLine) {
|
||||
double ex = (below - above) * (spacingmult - 1) + spacingadd;
|
||||
if (ex >= 0) {
|
||||
@@ -960,6 +977,15 @@ public class StaticLayout extends Layout {
|
||||
lines[off + TOP] = v;
|
||||
lines[off + DESCENT] = below + extra;
|
||||
|
||||
// special case for non-ellipsized last visible line when maxLines is set
|
||||
// store the height as if it was ellipsized
|
||||
if (!mEllipsized && currentLineIsTheLastVisibleOne) {
|
||||
// below calculation as if it was the last line
|
||||
int maxLineBelow = includePad ? bottom : below;
|
||||
// similar to the calculation of v below, without the extra.
|
||||
mMaxLineHeight = v + (maxLineBelow - above);
|
||||
}
|
||||
|
||||
v += (below - above) + extra;
|
||||
lines[off + mColumns + START] = end;
|
||||
lines[off + mColumns + TOP] = v;
|
||||
@@ -981,23 +1007,6 @@ public class StaticLayout extends Layout {
|
||||
start - widthStart, end - start);
|
||||
}
|
||||
|
||||
if (ellipsize != null) {
|
||||
// If there is only one line, then do any type of ellipsis except when it is MARQUEE
|
||||
// if there are multiple lines, just allow END ellipsis on the last line
|
||||
boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount);
|
||||
|
||||
boolean doEllipsis =
|
||||
(((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) &&
|
||||
ellipsize != TextUtils.TruncateAt.MARQUEE) ||
|
||||
(!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) &&
|
||||
ellipsize == TextUtils.TruncateAt.END);
|
||||
if (doEllipsis) {
|
||||
calculateEllipsis(start, end, widths, widthStart,
|
||||
ellipsisWidth, ellipsize, j,
|
||||
textWidth, paint, forceEllipsis);
|
||||
}
|
||||
}
|
||||
|
||||
mLineCount++;
|
||||
return v;
|
||||
}
|
||||
@@ -1105,7 +1114,7 @@ public class StaticLayout extends Layout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mEllipsized = true;
|
||||
mLines[mColumns * line + ELLIPSIS_START] = ellipsisStart;
|
||||
mLines[mColumns * line + ELLIPSIS_COUNT] = ellipsisCount;
|
||||
}
|
||||
@@ -1243,6 +1252,25 @@ public class StaticLayout extends Layout {
|
||||
return mEllipsizedWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total height of this layout.
|
||||
*
|
||||
* @param cap if true and max lines is set, returns the height of the layout at the max lines.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public int getHeight(boolean cap) {
|
||||
if (cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight == -1 &&
|
||||
Log.isLoggable(TAG, Log.WARN)) {
|
||||
Log.w(TAG, "maxLineHeight should not be -1. "
|
||||
+ " maxLines:" + mMaximumVisibleLineCount
|
||||
+ " lineCount:" + mLineCount);
|
||||
}
|
||||
|
||||
return cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight != -1 ?
|
||||
mMaxLineHeight : super.getHeight();
|
||||
}
|
||||
|
||||
private static native long nNewBuilder();
|
||||
private static native void nFreeBuilder(long nativePtr);
|
||||
private static native void nFinishBuilder(long nativePtr);
|
||||
@@ -1281,6 +1309,21 @@ public class StaticLayout extends Layout {
|
||||
private int mColumns;
|
||||
private int mEllipsizedWidth;
|
||||
|
||||
/**
|
||||
* Keeps track if ellipsize is applied to the text.
|
||||
*/
|
||||
private boolean mEllipsized;
|
||||
|
||||
/**
|
||||
* If maxLines is set, ellipsize is not set, and the actual line count of text is greater than
|
||||
* or equal to maxLine, this variable holds the ideal visual height of the maxLine'th line
|
||||
* starting from the top of the layout. If maxLines is not set its value will be -1.
|
||||
*
|
||||
* The value is the same as getLineTop(maxLines) for ellipsized version where structurally no
|
||||
* more than maxLines is contained.
|
||||
*/
|
||||
private int mMaxLineHeight = -1;
|
||||
|
||||
private static final int COLUMNS_NORMAL = 4;
|
||||
private static final int COLUMNS_ELLIPSIZE = 6;
|
||||
private static final int START = 0;
|
||||
|
||||
@@ -5157,7 +5157,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
* call {@link InputMethodManager#restartInput(View)}.</p>
|
||||
* @param hintLocales List of the languages that the user is supposed to switch to no matter
|
||||
* what input method subtype is currently used. Set {@code null} to clear the current "hint".
|
||||
* @see #getImeHIntLocales()
|
||||
* @see #getImeHintLocales()
|
||||
* @see android.view.inputmethod.EditorInfo#hintLocales
|
||||
*/
|
||||
public void setImeHintLocales(@Nullable LocaleList hintLocales) {
|
||||
@@ -7000,11 +7000,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
.setLineSpacing(mSpacingAdd, mSpacingMult)
|
||||
.setIncludePad(mIncludePad)
|
||||
.setBreakStrategy(mBreakStrategy)
|
||||
.setHyphenationFrequency(mHyphenationFrequency);
|
||||
.setHyphenationFrequency(mHyphenationFrequency)
|
||||
.setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
|
||||
if (shouldEllipsize) {
|
||||
builder.setEllipsize(mEllipsize)
|
||||
.setEllipsizedWidth(ellipsisWidth)
|
||||
.setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
|
||||
.setEllipsizedWidth(ellipsisWidth);
|
||||
}
|
||||
mHintLayout = builder.build();
|
||||
}
|
||||
@@ -7091,11 +7091,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
.setLineSpacing(mSpacingAdd, mSpacingMult)
|
||||
.setIncludePad(mIncludePad)
|
||||
.setBreakStrategy(mBreakStrategy)
|
||||
.setHyphenationFrequency(mHyphenationFrequency);
|
||||
.setHyphenationFrequency(mHyphenationFrequency)
|
||||
.setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
|
||||
if (shouldEllipsize) {
|
||||
builder.setEllipsize(effectiveEllipsize)
|
||||
.setEllipsizedWidth(ellipsisWidth)
|
||||
.setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
|
||||
.setEllipsizedWidth(ellipsisWidth);
|
||||
}
|
||||
// TODO: explore always setting maxLines
|
||||
result = builder.build();
|
||||
@@ -7367,9 +7367,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linecount = layout.getLineCount();
|
||||
int pad = getCompoundPaddingTop() + getCompoundPaddingBottom();
|
||||
int desired = layout.getLineTop(linecount);
|
||||
/*
|
||||
* Don't cap the hint to a certain number of lines.
|
||||
* (Do cap it, though, if we have a maximum pixel height.)
|
||||
*/
|
||||
int desired = layout.getHeight(cap);
|
||||
|
||||
final Drawables dr = mDrawables;
|
||||
if (dr != null) {
|
||||
@@ -7377,31 +7379,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
desired = Math.max(desired, dr.mDrawableHeightRight);
|
||||
}
|
||||
|
||||
desired += pad;
|
||||
desired += getCompoundPaddingTop() + getCompoundPaddingBottom();
|
||||
|
||||
if (mMaxMode == LINES) {
|
||||
/*
|
||||
* Don't cap the hint to a certain number of lines.
|
||||
* (Do cap it, though, if we have a maximum pixel height.)
|
||||
*/
|
||||
if (cap) {
|
||||
if (linecount > mMaximum) {
|
||||
desired = layout.getLineTop(mMaximum);
|
||||
|
||||
if (dr != null) {
|
||||
desired = Math.max(desired, dr.mDrawableHeightLeft);
|
||||
desired = Math.max(desired, dr.mDrawableHeightRight);
|
||||
}
|
||||
|
||||
desired += pad;
|
||||
linecount = mMaximum;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mMaxMode != LINES) {
|
||||
desired = Math.min(desired, mMaximum);
|
||||
}
|
||||
|
||||
if (mMinMode == LINES) {
|
||||
int linecount = layout.getLineCount();
|
||||
if (linecount < mMinimum) {
|
||||
desired += getLineHeight() * (mMinimum - linecount);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user