Я сейчас тоже был занят этой проблемой.
К сожалению, мне пока не удалось установить исходный код, но я почти уверен, что измерения текста (как getTextBounds(), так и MeasureText()) сильно отличаются от реального вывода текста, особенно для небольших размеров шрифта (как видно на снимке экрана Морица). Я предполагаю, что методы измерения используют ширину с плавающей запятой для char, а реальный текстовый вывод использует 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
Поэтому, на мой взгляд, единственный способ добиться очень точного автоматического масштабирования текста - это: а) автоматически масштабировать его, измеряя и устанавливая размер текста; б) выводить его char за char с помощью самостоятельно вычисляемого приращения.
К сожалению, это работает только для моноширинных шрифтов. Для других шрифтов это будет сложнее, но тоже возможно.
person
user2328447
schedule
26.05.2013