Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/snackbar/TemplatePreservingTextView.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/TemplatePreservingTextView.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/TemplatePreservingTextView.java |
| index 36f4759d422ccde16430d13b43f0edeb6704d5bd..480670fc181d80be72a7ddffc4c4920a477aee7f 100644 |
| --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/TemplatePreservingTextView.java |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/TemplatePreservingTextView.java |
| @@ -13,13 +13,21 @@ import android.util.AttributeSet; |
| import android.widget.TextView; |
| /** |
| - * A {@link AppCompatTextView} that properly clips content within a template, instead of clipping |
| - * the templated content. |
| + * A {@link AppCompatTextView} that truncates content within a template, instead of truncating |
| + * the template text. Truncation only happens if maxLines is set to 1 and there's not enough space |
| + * to display the entire content. |
| + * |
| + * For example, given the following template and content |
| + * Template: "%s was closed" |
| + * Content: "https://www.google.com/webhp?sourceid=chrome-instant&q=potato" |
| + * |
| + * the TemplatePreservingTextView would truncate the content but not the template text: |
| + * "https://www.google.com/webh... was closed" |
| */ |
| public class TemplatePreservingTextView extends AppCompatTextView { |
| - private static final String DEFAULT_TEMPLATE = "%1$s"; |
|
Ian Wen
2015/07/09 00:39:26
Is it deleted?
newt (away)
2015/07/09 01:16:12
Yes. Now we just use "null" to indicate that templ
|
| private String mTemplate; |
| - private CharSequence mContent; |
| + private CharSequence mContent = ""; |
| + private CharSequence mVisibleText; |
| /** |
| * Builds an instance of an {@link TemplatePreservingTextView}. |
| @@ -31,41 +39,38 @@ public class TemplatePreservingTextView extends AppCompatTextView { |
| } |
| /** |
| - * Update template for undo text |
| - * @param template Template format string (eg. "Close %s") |
| + * Sets the template format string. setText() must be called after calling this method for the |
| + * new template text to take effect. |
| + * |
| + * @param template Template format string (e.g. "Closed %s"), or null. If null is passed, this |
| + * view acts like a normal TextView. |
| */ |
| public void setTemplate(String template) { |
| - mTemplate = TextUtils.isEmpty(template) ? DEFAULT_TEMPLATE : template; |
| + mTemplate = TextUtils.isEmpty(template) ? null : template; |
| } |
| /** |
| * This will take {@code text} and apply it to the internal template, building a new |
| - * {@link String} to set. This {code text} will be automatically truncated to fit within |
| + * {@link String} to set. This {@code text} will be automatically truncated to fit within |
| * the template as best as possible, making sure the template does not get clipped. |
| */ |
| @Override |
| public void setText(CharSequence text, BufferType type) { |
| - final int availWidth = getWidth() - getPaddingLeft() - getPaddingRight(); |
| - setClippedText(text, availWidth); |
| + mContent = text != null ? text : ""; |
| + setContentDescription(mTemplate == null ? mContent : String.format(mTemplate, mContent)); |
| + updateVisibleText(0, true); |
| } |
| @Override |
| protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| final int availWidth = |
| MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight(); |
| - setClippedText(mContent, availWidth); |
| - |
| + updateVisibleText(availWidth, |
| + MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED); |
| super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
| } |
| - private void setClippedText(CharSequence text, int availWidth) { |
| - mContent = text != null ? text : ""; |
| - |
| - if (mTemplate == null) { |
| - super.setText(mContent, BufferType.SPANNABLE); |
| - return; |
| - } |
| - |
| + private CharSequence getTruncatedText(int availWidth) { |
| final TextPaint paint = getPaint(); |
| // Calculate the width the template takes. |
| @@ -79,13 +84,25 @@ public class TemplatePreservingTextView extends AppCompatTextView { |
| CharSequence clipped = TextUtils.ellipsize(mContent, paint, contentWidth, TruncateAt.END); |
| // Build the full string, which should fit within availWidth. |
| - String finalContent = String.format(mTemplate, clipped); |
| + return String.format(mTemplate, clipped); |
| + } |
| + |
| + private void updateVisibleText(int availWidth, boolean unspecifiedWidth) { |
| + CharSequence visibleText; |
| + if (mTemplate == null) { |
| + visibleText = mContent; |
| + } else if (getMaxLines() != 1 || unspecifiedWidth) { |
| + visibleText = String.format(mTemplate, mContent); |
| + } else { |
| + visibleText = getTruncatedText(availWidth); |
| + } |
| - // BufferType.SPANNABLE is required so that TextView.getIterableTextForAccessibility() |
| - // doesn't call our custom setText(). See crbug.com/449311 |
| - super.setText(finalContent, BufferType.SPANNABLE); |
| + if (!visibleText.equals(mVisibleText)) { |
| + mVisibleText = visibleText; |
| - // Set the content description to the non-ellipsized text |
| - setContentDescription(String.format(mTemplate, mContent)); |
| + // BufferType.SPANNABLE is required so that TextView.getIterableTextForAccessibility() |
| + // doesn't call our custom setText(). See crbug.com/449311 |
| + super.setText(mVisibleText, BufferType.SPANNABLE); |
| + } |
| } |
| } |