Intereting Posts
Можно ли предварительно загружать данные в WebViews в дочерних элементах RecyclerView? Нарисуйте растровое изображение, разбитое на Rect android FragmentActivity: нельзя отбрасывать из фрагмента в производный класс Службы Google Location Services и службы поиска на Android Android: доступ к изображениям из активов / доступных папок Как добавить «Android Project» в меню File> New> _____ в Eclipse? Повторно подписать Android Apk Обнаруживать, если в настоящее время прокрутка веб-страницы на Android Android Market – консоль разработчика: включен маркетинг / отключен? Одновременный доступ к различным членам одного и того же объекта в Java Должен ли я оставить bluetooth-отражение взлома в производственном коде? Переход от общего элемента не работает Spinner с многострочными элементами перекрывает выбранный элемент на Froyo Ошибка заполнения после того, как base64decoding подписи Google после покупки в приложении WebView, похоже, не разрушается после ухода из бизнеса?

Как надежно определить ширину многострочной строки?

Я пытаюсь вычислить ширину многострочного абзаца текста. Насколько я знаю, единственным классом, который может это сделать в Android, является класс StaticLayout (или DynamicLayout). При использовании этого класса я не получаю правильную длину текста, но измеренные размеры иногда меньше, а иногда и больше, в зависимости от размера текста.

Поэтому я в основном ищу способ надежного измерения ширины многострочной текстовой строки.

На следующем рисунке показано, как измеренная ширина расходится с фактической длиной текста в разных размерах текста. Расходящийся текст и измерение

Создается скриншот, запускающий следующий код в пользовательском представлении:

@Override protected void onDraw( Canvas canvas ) { for( int i = 0; i < 15; i++ ) { int startSize = 10; int curSize = i + startSize; paint.setTextSize( curSize ); String text = i + startSize + " - " + TEXT_SNIPPET; layout = new StaticLayout( text, paint, Integer.MAX_VALUE, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true ); float top = STEP_DISTANCE * i; float measuredWidth = layout.getLineMax( 0 ); canvas.drawRect( 0, top, measuredWidth, top + curSize, bgPaint ); canvas.drawText( text, 0, STEP_DISTANCE * i + curSize, paint ); } } 

Solutions Collecting From Web of "Как надежно определить ширину многострочной строки?"

Вы можете попробовать использовать текстовые ограничения.

 private int calculateWidthFromFontSize(String testString, int currentSize) { Rect bounds = new Rect(); Paint paint = new Paint(); paint.setTextSize(currentSize); paint.getTextBounds(testString, 0, testString.length(), bounds); return (int) Math.ceil( bounds.width()); } private int calculateHeightFromFontSize(String testString, int currentSize) { Rect bounds = new Rect(); Paint paint = new Paint(); paint.setTextSize(currentSize); paint.getTextBounds(testString, 0, testString.length(), bounds); return (int) Math.ceil( bounds.height()); } 

У меня была аналогичная проблема, когда измеренная ширина текста была немного разряжена, как только вы установите шрифт на краску, это исчезнет. Поэтому, прежде чем использовать объект paint в StaticLayout просто установите Typeface:

 textPaint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL)) 

Или любой другой шрифт, который вы хотите.

Здесь вы можете получить многострочную ширину любой длины текста. usableButtonWidth может быть заданным текстовым пространством. Я использовал usableButtonWidth = ширина кнопки – padding. Но любое значение по умолчанию может быть использовано.

Используя StaticLayout, вы можете получить высоту текста для usableButtonWidth . Затем я просто пытаюсь уменьшить доступную ширину, уменьшив ее на 1px в цикле. Если высота возрастает, то мы узнаем, что ранее использовавшаяся ширина была максимально допустимой.

Возвращайте это значение как ширину многострочного текста.

 private int getTextWidth(){ if(this.getText().length() != 0){ Paint textPaint = new Paint(); Rect bounds = new Rect(); textPaint.setTextSize(this.getTextSize()); if(mTypeface != null){ textPaint.setTypeface(mTypeface); } String buttonText = this.getText().toString(); textPaint.getTextBounds(buttonText, 0, buttonText.length(), bounds); if(bounds.width() > usableButtonWidth){ TextPaint longTextPaint = new TextPaint(); longTextPaint.setTextSize(this.getTextSize()); if(mTypeface != null){ longTextPaint.setTypeface(mTypeface); } StaticLayout staticLayout = new StaticLayout(this.getText(), longTextPaint, usableButtonWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); int textLineCount = (int)Math.ceil(staticLayout.getHeight() / bounds.height()); int multiLineTextWidth = usableButtonWidth; while ((int)Math.ceil(staticLayout.getHeight() / bounds.height()) == textLineCount && multiLineTextWidth > 1){ multiLineTextWidth--; staticLayout = new StaticLayout(this.getText(), longTextPaint, multiLineTextWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); } return multiLineTextWidth+1; } else { return bounds.width(); } } else { return 0; } }