1

I have some code that measure the width of an android textView and the text to display in it.

final ViewTreeObserver[] viewTreeObserver = {myAccountView.getViewTreeObserver()};
    viewTreeObserver[0].addOnPreDrawListener(
        new OnPreDrawListener() {
          @Override
          public boolean onPreDraw() {
            myAccountView.setText(R.string.og_my_account_desc_long_length);
            int chipWidth = myAccountView.getMeasuredWidth();
            if (chipWidth > 0) {
              setChipTextWithCorrectLength(chipWidth);
              viewTreeObserver[0] = myAccountView.getViewTreeObserver();
              if (viewTreeObserver[0].isAlive()) {
                viewTreeObserver[0].removeOnPreDrawListener(this);
              }
            }
            return true;
          }
        });
  }

  private void setChipTextWithCorrectLength(int chipWidth) {
    String desc =
        setChipTextWithCorrectLength(
            getContext().getString(R.string.og_my_account_desc_long_length),
            getContext().getString(R.string.og_my_account_desc_meduim_length),
            getContext().getString(R.string.og_my_account_desc_short_length),
            chipWidth);
    myAccountView.setText(desc);
  }

  @VisibleForTesting
  String setChipTextWithCorrectLength(
      String longDesc, String mediumDesc, String shortDesc, int clipWidth) {
    if (textWidthPixels(longDesc) > clipWidth) {
      if (textWidthPixels(mediumDesc) > clipWidth) {
        return shortDesc;
      } else {
        return mediumDesc;
      }
    }
    return longDesc;
  }

  public float textWidthPixels(String text) {
    TextPaint textPaint = myAccountView.getPaint();
    return textPaint.measureText(text);
  }

I changed my device a11y to the biggest font and biggest display.

I see in the UI the text is truncated (ellipsized)

enter image description here

but my measurements show the text width (503 pixels) is smaller than the text-view width (587 px).

how can it be?

how should i measure them differently so my code will also indicate the text width is bigger than the text-view width?

Edit:

i have tried to add padding, but it didn't change. changing to a11y truncated the long text instead of choosing shorter text.

  public float textWidthPixels(String text) {
    TextPaint textPaint = myAccountView.getPaint();
    View parent = (View) myAccountView.getParent();
    float width = textPaint.measureText(text);

    int paddingLeft = parent.getPaddingLeft();
    int paddingRight = parent.getPaddingRight();
    return width - (paddingLeft + paddingRight);

  }

Edit:

i have tried to calculate chipWidth considering its paddings, but still textSize make the text truncate while it's drawn size in code comes shorter than the view size

int chipWidth = myAccountView.getMeasuredWidth() - myAccountView.getPaddingLeft() - myAccountView.getPaddingRight();
Elad Benda
  • 35,076
  • 87
  • 265
  • 471
  • You should also consider the padding of the `TextView`. Since the text should live within the padding the available width for text is not `TextView.measuredWidth` but `TextView.measuredWidth - TextView.paddingLeft - TextView.paddingRight`. – Durgadass S Sep 02 '18 at 07:29
  • i have tried to add padding, but it didn't change. changing to a11y truncated the long text instead of choosing shorter text. – Elad Benda Sep 02 '18 at 12:45
  • Calculate chip width as 'int chipWidth = myAccountView.getMeasuredWidth() - myAccountView.getPaddingLeft() - myAccountView.getPaddingRight();'. – Durgadass S Sep 02 '18 at 17:23
  • @DurgadassS why would font size change the view's padding? – Elad Benda Sep 02 '18 at 18:01
  • From the image I see that myAccountView expands up to the rounded edges. It's width spans to the rounded edges. But the text starts and ends after the end of left half circle and before the beginning of right half circle. So the padding of myAccountView should be considered. In your edit you considered the padding of myAccountView's parent which has no relevance. – Durgadass S Sep 03 '18 at 04:27
  • And if you do this don't do in textWidthPixels(). Now you are subtracting the padding which further reduces the text width which won't work according to rest of your code. Just calculate the chipWidth with padding considered. – Durgadass S Sep 03 '18 at 04:33
  • @DurgadassS i have tried to calculate chipWidth considering its paddings, but still textSize make the text truncate while it's drawn size in code comes shorter than the view size int chipWidth = myAccountView.getMeasuredWidth() - myAccountView.getPaddingLeft() - myAccountView.getPaddingRight(); – Elad Benda Sep 03 '18 at 08:51
  • Sorry, then I have no clue... – Durgadass S Sep 03 '18 at 09:02
  • @DurgadassS it actually worked. checked again. can you please write it as an answer and I will mark it as correct? – Elad Benda Sep 03 '18 at 09:32
  • Good to hear that. Actually I posted the solution as comment because it's just a guess and I am not sure whether this will work. – Durgadass S Sep 03 '18 at 11:36

2 Answers2

1

It seems that a solution has been found , but a few points that I would like to present based on my research.

int textViewWidth = textView.getMeasuredWidth();

returns the width of the textView including any paddings.

For the enclosing text :

  1. can use measureText() :

    TextPaint paint = textView.getPaint(); int textWidth = (int)paint.measureText(textView.getText().toString());

  2. Using getTextBounds()

    TextPaint paint = textView.getPaint(); Rect bounds = new Rect(); paint.getTextBounds(textView.getText().toString(),0,textView.getText().toString().length(),bounds); int textWidth = bounds.width();

The comparing these values by adding the padding values to the textWidth or subtracting from the textViewWidth is comparision base for you.

For Difference between the above two ways

You could also try textView.getLayout().getEllipsisStart(0) in case your textView is singleline directly as you comparison base(rather than computing the widths) . It return the index from which the text gets truncated else returns 0.

I would also recommend you to see Autosizing TextViews .

Support Library 26.0 provides full support to the autosizing TextView feature to Android 4.0 (API level 14) and higher.

Elad Benda
  • 35,076
  • 87
  • 265
  • 471
Kaveri
  • 1,060
  • 2
  • 12
  • 21
0

From the image I see that myAccountView expands up to the rounded edges. It's width spans to the rounded edges. But the text starts and ends after the end of left half circle and before the beginning of right half circle. So the padding of myAccountView should be considered. In your edit you considered the padding of myAccountView's parent which has no relevance.

While measuring the chipWidth the padding should be considered.

int chipWidth = myAccountView.getMeasuredWidth() - myAccountView.getPaddingLeft() - myAccountView.getPaddingRight();
Durgadass S
  • 1,098
  • 6
  • 13