Текстовый вид Android Jelly Bean с пользовательским шрифтом, не подходит

Просто для информации, я просмотрел все ресурсы, которые рассказывают, как разместить текст в границах.

  1. Автоматически масштабировать текст TextView, чтобы он соответствовал границам
  2. Как масштабировать/изменять размер текста, чтобы он соответствовал TextView?
  3. Как настроить размер шрифта текста в соответствии с текстовым представлением
  4. Проблема разницы в размере шрифта Android на пряниках и мармеладках

Но моя главная проблема заключается в том, что я не хочу изменять размер шрифта, чтобы он соответствовал границам текста. У меня есть TextView, который берет Custom Font из папки assets. Кроме того, пользователь может изменить размер шрифта через slider. Все на устройствах ниже Jelly Bean проблем не возникает, но на Jelly Bean устройствах текст не соответствует границам TextView, как показано на изображении текст не подходит

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

  1. Рассчитать длину текста, которая помещается на ширину экрана
  2. Затем добавьте новую строку к строке этой конкретной длины.
  3. Поскольку длина текста будет большой, я боюсь использовать StringBuffer и StringBuilder, так как они могут легко привести к out of memory exception
  4. Таким образом, TextView автоматически вычисляет коэффициент вставки новостной строки, когда она достигает видимой длины.

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

public class AutoResizeTextView extends TextView {

private boolean forFirstTime = true;

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



private void monitorChanges() {
    final int widthLimit = getMeasuredWidth() - getCompoundPaddingLeft()
            - getCompoundPaddingRight();
    if (widthLimit <= 0) {
        return;
    }
    final String mainText = getText().toString();
    final float actualTextWidth = getPaint().measureText(mainText);

    forFirstTime = false;

    setText("");
    String[] overallText = inputText.split("\\n");

    for(int j=0;j<overallText.length;j++){
        String mainText =overallText[j];
        int length = mainText.length();
        int lineNumber = Math.round(getPaint().measureText(mainText)/ widthLimit);
        int wordLimit = (int) Math.round(length / (lineNumber * 1.3));
        //wordLimit+=2;
        if (wordLimit < length) {
            int count = Math.round(length / wordLimit);
            int startIndex = -1, endIndex = -1;
            for (int i = 0; i < count; i++) {
                startIndex = wordLimit * i;
                endIndex = wordLimit * (i + 1);
             append(mainText.substring(startIndex, endIndex) + "\n");
            }
        append(mainText.toString().substring(endIndex, length)+"\n");
        }
   }
}

Теперь хочу чтобы слова не ломались,как выставлено по умолчанию android EditText на wrap_content params,где весь текст переносится на следующую строку,если он становится большим чтобы поместиться. И далее формула расчета wordLimit не точная, я просто хочу узнать точную длину string которая подходит к widthLimit из TextView/EditText

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


person laaptu    schedule 13.01.2013    source источник


Ответы (1)


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

public class AutoResizeTextView extends TextView {


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

private boolean forFirstTime = true;
    // Text view line spacing multiplier
    private float mSpacingMult = 1.0f;

    // Text view additional line spacing
    private float mSpacingAdd = 0.0f;

private void monitorChanges() {
    int widthLimit = getMeasuredWidth() - getCompoundPaddingLeft()
            - getCompoundPaddingRight();

    if (widthLimit <= 0) {
        return;
    }
    String inputText = getText().toString();

    forFirstTime = false;

    setText("");
    String[] overallText = inputText.split("\\n");

    TextPaint textPaint = getPaint();
    for(int j=0;j<overallText.length;j++){
        String mainText =overallText[j];
        StaticLayout layout = new    StaticLayout(mainText,textPaint,widthLimit,Alignment.ALIGN_NORMAL,
                mSpacingMult,mSpacingAdd,false);        
        if(layout.getLineCount()>0){
            for(int i=0;i<layout.getLineCount();i++){
                int start =layout.getLineStart(i);
                int end =layout.getLineEnd(i);
                append(mainText.substring(start, end)+"\n");
            }
        }

    }   
}
}

Но я не совсем доволен результатом ;)

person laaptu    schedule 17.01.2013