Как масштабировать / изменять размер текста, чтобы соответствовать TextView ?

? RyanM @ | Original: StackOverFlow
---

Я пытаюсь создать метод для изменения размера многострочный текст вTextView таким образом, что она вписывается в пределах ( как X и Y размеры)TextView .

В настоящее время, у меня есть кое-что, но все это делает изменять размер текста таким образом, что толькопервая буква / символ текста заполняет размерыTextView (т.е. толькопервая буква просмотра, и это очень большой) . Мне это нужно, чтобы соответствовать все строки текста в пределах от TextView .

Вот то, что я до сих пор :

public static void autoScaleTextViewTextToHeight(TextView tv)
{
    final float initSize = tv.getTextSize();
    //get the width of the view's back image (unscaled).... 
    float minViewHeight;
    if(tv.getBackground()!=null)
    {
      minViewHeight = tv.getBackground().getIntrinsicHeight();
    }
    else
    {
      minViewHeight = 10f;//some min.
    }
    final float maxViewHeight = tv.getHeight() - (tv.getPaddingBottom()+tv.getPaddingTop())-12;// -12 just to be sure
    final String s = tv.getText().toString();

    //System.out.println(""+tv.getPaddingTop()+"/"+tv.getPaddingBottom());

    if(minViewHeight >0 && maxViewHeight >2)
    {
      Rect currentBounds = new Rect();
      tv.getPaint().getTextBounds(s, 0, s.length(), currentBounds);
      //System.out.println(""+initSize);
      //System.out.println(""+maxViewHeight);
      //System.out.println(""+(currentBounds.height()));

      float resultingSize = 1;
      while(currentBounds.height() < maxViewHeight)
      {
        resultingSize ++;
        tv.setTextSize(resultingSize);

        tv.getPaint().getTextBounds(s, 0, s.length(), currentBounds);
        //System.out.println(""+(currentBounds.height()+tv.getPaddingBottom()+tv.getPaddingTop()));
        //System.out.println("Resulting: "+resultingSize);
      }
      if(currentBounds.height()>=maxViewHeight)
      {
        //just to be sure, reduce the value
        tv.setTextSize(resultingSize-1);
      }
    }
}

Я думаю, чтопроблема в использовании tv.getPaint().getTextBounds(...) . Это всегда возвращает небольшое количество для границы текста ... мала по сравнению с tv.getWidth() и tv.getHeight() ценностей ... даже еслиразмер текста гораздо больше, чем ширина или высотаTextView .

---

Top 5 ответ

1snctln @

Может быть, попробовать установить http://developer.android.com/reference/android/widget/TextView.html#setHorizontallyScrolling%28boolean%29 истина, прежде чем принимать текстовые измерения, так чтоTextView не пытается макет ваш текст на несколько строк

2RyanM @

Я был в состоянии ответить на мой собственный вопрос, используя следующий код (см ниже), но мое решение было очень специфичные для данного приложения . Например, это, вероятно, только хорошо выглядеть и / или работать наTextView размером ок. 1/2экрана (с также 40px верхнее поле и 20px боковых краев ... нет нижнего поля ) .

Используя этот подход, хотя, вы можете создать свой собственный похожая реализация . Статический метод в основном просто смотрит на количество символов и определяет коэффициент масштабирования обратиться к размер текста в TextView, а затем постепенно увеличивает размер текста, чтобы общая высота ( по оценкам, рост - используя ширину текста, текст высота и ширина TextView ) только ниже, чем в TextView . Параметры, необходимые для определения коэффициента масштабирования ( т.е.если / иначе, если заявления ) были установлены наугад и - проверки. Вы, вероятно, придется поиграть с цифрами, чтобы заставить его работать для вашего конкретного применения.

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

public static void autoScaleTextViewTextToHeight(final TextView tv, String s)
    {       
        float currentWidth=tv.getPaint().measureText(s);
        int scalingFactor = 0;
        final int characters = s.length();
        //scale based on # of characters in the string
        if(characters<5)
        {
            scalingFactor = 1;
        }
        else if(characters>=5 && characters<10)
        {
            scalingFactor = 2;
        }
        else if(characters>=10 && characters<15)
        {
            scalingFactor = 3;
        }
        else if(characters>=15 && characters<20)
        {
            scalingFactor = 3;
        }
        else if(characters>=20 && characters<25)
        {
            scalingFactor = 3;
        }
        else if(characters>=25 && characters<30)
        {
            scalingFactor = 3;
        }
        else if(characters>=30 && characters<35)
        {
            scalingFactor = 3;
        }
        else if(characters>=35 && characters<40)
        {
            scalingFactor = 3;
        }
        else if(characters>=40 && characters<45)
        {
            scalingFactor = 3;
        }
        else if(characters>=45 && characters<50)
        {
            scalingFactor = 3;
        }
        else if(characters>=50 && characters<55)
        {
            scalingFactor = 3;
        }
        else if(characters>=55 && characters<60)
        {
            scalingFactor = 3;
        }
        else if(characters>=60 && characters<65)
        {
            scalingFactor = 3;
        }
        else if(characters>=65 && characters<70)
        {
            scalingFactor = 3;
        }
        else if(characters>=70 && characters<75)
        {
            scalingFactor = 3;
        }
        else if(characters>=75)
        {
            scalingFactor = 5;
        }

        //System.out.println(((int)Math.ceil(currentWidth)/tv.getWidth()+scalingFactor));
        //the +scalingFactor is important... increase this if nec. later
        while((((int)Math.ceil(currentWidth)/tv.getWidth()+scalingFactor)*tv.getTextSize())<tv.getHeight())
        {
            tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, tv.getTextSize()+0.25f);
            currentWidth=tv.getPaint().measureText(s);
            //System.out.println(((int)Math.ceil(currentWidth)/tv.getWidth()+scalingFactor));
        }

        tv.setText(s);
    }

Thanks.

3Octavian Damiean @

Если ваш Единственным требованием является, чтобы иметьтекст автоматически разделит и продолжить на следующей строке ивысота не важно то просто это так .

<TextView
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:maxEms="integer"
    android:width="integer"/>

Это будет иметь свой ​​TextView оболочку для его содержимое вертикально, в зависимости от вашего стоимости maxEms .

4vsm @

Убедитесь в том, что мое решение поможет вам:

http://stackoverflow.com/questions/5033012/auto-scale-textview-text-to-fit-within-bounds/5280436#5280436

5Chase @

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

http://stackoverflow.com/questions/5033012/auto-scale-textview-text-to-fit-within-bounds/5535672#5535672