diff --git a/mobile/android/base/home/FadedTextView.java b/mobile/android/base/home/FadedTextView.java
index 8394be13aa13..636e7d59a9ee 100644
--- a/mobile/android/base/home/FadedTextView.java
+++ b/mobile/android/base/home/FadedTextView.java
@@ -11,6 +11,7 @@ import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
+import android.text.Layout;
import android.util.AttributeSet;
import android.widget.TextView;
@@ -23,10 +24,10 @@ import org.mozilla.gecko.R;
public class FadedTextView extends TextView {
// Width of the fade effect from end of the view.
- private int mFadeWidth;
+ private final int mFadeWidth;
- // Padding for compound drawables.
- private int mCompoundPadding;
+ // Shader for the fading edge.
+ private FadedTextGradient mTextGradient;
public FadedTextView(Context context) {
this(context, null);
@@ -39,42 +40,70 @@ public class FadedTextView extends TextView {
public FadedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ setSingleLine(true);
+ setEllipsize(null);
+
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FadedTextView);
mFadeWidth = a.getDimensionPixelSize(R.styleable.FadedTextView_fadeWidth, 0);
a.recycle();
-
- mCompoundPadding = getCompoundDrawablePadding();
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void onDraw(Canvas canvas) {
- int width = getMeasuredWidth();
+ private int getAvailableWidth() {
+ return getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();
+ }
- // Layout doesn't return a proper width for getWidth().
- // Instead check the width of the first line, as we've restricted to just one line.
- if (getLayout().getLineWidth(0) > width) {
- final Drawable leftDrawable = getCompoundDrawables()[0];
- int drawableWidth = 0;
- if (leftDrawable != null) {
- drawableWidth = leftDrawable.getIntrinsicWidth() + mCompoundPadding;
- width -= drawableWidth;
- }
-
- int color = getCurrentTextColor();
- float stop = ((float) (width - mFadeWidth) / (float) width);
- LinearGradient gradient = new LinearGradient(0, 0, width, 0,
- new int[] { color, color, 0x0 },
- new float[] { 0, stop, 1.0f - (drawableWidth / width) },
- Shader.TileMode.CLAMP);
- getPaint().setShader(gradient);
- } else {
- getPaint().setShader(null);
+ private boolean needsEllipsis() {
+ final int width = getAvailableWidth();
+ if (width <= 0) {
+ return false;
}
- // Do a default draw.
+ final Layout layout = getLayout();
+ return (layout != null && layout.getLineWidth(0) > width);
+ }
+
+ private void updateGradientShader() {
+ final int color = getCurrentTextColor();
+ final int width = getAvailableWidth();
+
+ final boolean needsNewGradient = (mTextGradient == null ||
+ mTextGradient.getColor() != color ||
+ mTextGradient.getWidth() != width);
+
+ final boolean needsEllipsis = needsEllipsis();
+ if (needsEllipsis && needsNewGradient) {
+ mTextGradient = new FadedTextGradient(width, mFadeWidth, color);
+ }
+
+ getPaint().setShader(needsEllipsis ? mTextGradient : null);
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ updateGradientShader();
super.onDraw(canvas);
}
+
+ private static class FadedTextGradient extends LinearGradient {
+ private final int mWidth;
+ private final int mColor;
+
+ public FadedTextGradient(int width, int fadeWidth, int color) {
+ super(0, 0, width, 0,
+ new int[] { color, color, 0x0 },
+ new float[] { 0, ((float) (width - fadeWidth) / (float) width), 1.0f },
+ Shader.TileMode.CLAMP);
+
+ mWidth = width;
+ mColor = color;
+ }
+
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getColor() {
+ return mColor;
+ }
+ }
}
diff --git a/mobile/android/base/resources/values-large-land-v11/styles.xml b/mobile/android/base/resources/values-large-land-v11/styles.xml
index 89cd9248d841..6219814bb712 100644
--- a/mobile/android/base/resources/values-large-land-v11/styles.xml
+++ b/mobile/android/base/resources/values-large-land-v11/styles.xml
@@ -11,6 +11,8 @@