Я теперь тоже был занят этой проблемой.
К сожалению, мне пока не удалось установить собственный источник, но я почти уверен, что текстовые измерения (как getTextBounds () и measureText ())сильно отличаются от реального вывода текста, особенно для шрифтов небольшого размера (как видно на скриншоте Морица ).Я предполагаю, что методы измерения используют ширину с плавающей точкой для символа, а реальный текстовый вывод использует int (предположительно из-за производительности).Это, конечно, потерпит неудачу, если вам нужен абсолютно точный размер (например, для автоматического изменения размера).Я немного поэкспериментировал с моноширинным шрифтом.Это изображение показывает некоторые из этих экспериментов:
.
Масштаб текста в этих экспериментах был установлен путем автоматического масштабирования.
В верхнем ряду я создал блоки с целочисленным приращением.Они соответствуют выводу текста Android.Видите ли, последний шифр не соответствует экрану!
Во 2-й строке ящики были созданы с приращением с плавающей точкой.Боксы лучше соответствуют экрану, но не соответствуют выводу текста на Android!
В последней строке поля были увеличены на величину с плавающей запятой, и текст выводился символ за символом с тем же шагом.И поля, и символы подходят идеально.
В моем заключении, в настоящее время невозможно установить вывод текста на Android с точной шириной.Кажется, проблема не в методах измерения, которые достаточно точны.Кажется, проблема в том, что вы не можете установить точную ширину текста с помощью setTextSize ().
Попробуйте воспроизвести следующее:
float width = 100; // define a width which should be achieved
m_textPaint.setTextSize( 100 ); // set a text size surely big enough
Rect r = new Rect();
String s = new String("This is a test text");
m_textPaint.getTextBounds( s, 0, s.length(), r ); // measure the text with a random size
float fac = width / r.width(); // compute the factor, which will scale the text to our target width
Log.i( "MyTestOutput", "current text width:" + r.width() );
Log.i( "MyTestOutput", "wanted text width:" + width );
Log.i( "MyTestOutput", "factor:" + fac );
Log.i( "MyTestOutput", "expected result:" + (float) r.width() * fac );
m_textPaint.setTextSize( m_textPaint.getTextSize() * fac );
m_textPaint.getTextBounds( s, 0, s.length(), r ); // now final measurement: whats the real width?
Log.i( "MyTestOutput", "real result:" + r.width() );
Я получаю вывод:
05-26 12: 18: 18.420: I / MyTestOutput (23607): текущая ширина текста: 1125
05-26 12: 18: 18.425: I / MyTestOutput (23607):ширина полезного текста: 100,0
05-26 12: 18: 18,425: I / MyTestOutput (23607): коэффициент: 0,08888889
05-26 12: 18: 18,425: I / MyTestOutput (23607): ожидаемый результат: 100.0
05-26 12: 18: 18.430: I / MyTestOutput (23607): реальный результат: 94
Так что, на мой взгляд, единственный способдобиться очень точного автоматически масштабируемого текста, а) а) автоматически масштабировать его, измеряя и задавая размер текста б) выводить его символ за символом с помощью собственного вычисленного приращения.
К сожалению, это работает только для моноширинных шрифтов.Для других шрифтов это будет сложнее, но также возможно.