android view width is not bigger when a11y is changed to big font

142 Views Asked by At

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();
2

There are 2 best solutions below

0
On BEST ANSWER

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();
0
On

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.