Можно указать текст TextView для масштабирования, чтобы вписаться в TextView?

Есть ли какое-либо свойство TextView, которое можно указать так, чтобы его текст (размер шрифта) динамически масштабировался, чтобы поместиться в TextView? (Аналогично функции автоматического сжатия iPhone.)

Если нет, то есть ли какие-нибудь хорошие, простые решения, с которыми кто-либо сталкивался или придумывал, чтобы решить эту проблему? (И такой, что это будет работать и для неанглийских языков.)

1 ответ

Решение

Перейдя по ссылке V4l3ri4 и появившимся оттуда ссылкам, я пришел к следующему голому решению, которое непрерывно сжимает текст в TextView до тех пор, пока он не уместится по ширине в TextView:

public class FontFitTextView extends TextView
{
  private float maxTextSizePx;

  public FontFitTextView(Context context)
  {
    super(context);
    initialise();
  }

  public FontFitTextView(Context context, AttributeSet attrs)
  {
    super(context, attrs);
    initialise();
  }

  public FontFitTextView(Context context, AttributeSet attrs, int defStyle)
  {
    super(context, attrs, defStyle);
    initialise();
  }

  /** Sets the maximum text size as the text size specified to use for this View.*/
  private void initialise()
  {
    maxTextSizePx = getTextSize(); 
  }

  /** Reduces the font size continually until the specified 'text' fits within the View (i.e. the specified 'viewWidth').*/
  private void refitText(String text, int viewWidth)
  { 
    if (viewWidth > 0)
    {
      TextPaint textPaintClone = new TextPaint();
      textPaintClone.set(getPaint());

      int availableWidth = viewWidth - getPaddingLeft() - getPaddingRight();
      float trySize = maxTextSizePx;

      // note that Paint text size works in px not sp
      textPaintClone.setTextSize(trySize); 

      while (textPaintClone.measureText(text) > availableWidth)
      {
        trySize--;
        textPaintClone.setTextSize(trySize);
      }

      setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
    }
  }

  @Override
  protected void onTextChanged(final CharSequence text, final int start, final int lengthBefore, final int lengthAfter)
  {
    super.onTextChanged(text, start, lengthBefore, lengthAfter);

    refitText(text.toString(), getWidth());
  }

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh)
  {
    super.onSizeChanged(w, h, oldw, oldh);

    if (w != oldw)
      refitText(getText().toString(), w);
  }
}

Пример использования следующий:

<view
  class="com.mycompany.myapp.views.FontFitTextView"
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:layout_weight="1"
  android:singleLine="true" />

Я понимаю, что эта реализация может быть оптимизирована и расширена, но я просто пытаюсь показать простое решение, которое вы можете расширить или изменить по мере необходимости.

Да, и если вам нужна кнопка, которая сокращает размер текста, а не TextView, просто используйте код, точно такой же, как указано выше, но расширяйте Button вместо TextView.

Другие вопросы по тегам