Intereting Posts
Что такое хороший способ получить список файлов из каталога (на) на SD-карте? Высота ListView заполняет весь экран, хотя устанавливается как wrap_content Как получить BackgroundColorSpan для выбранного текста в android Невозможно разрешить атрибут из пространства имен android. Realm – как закрыть экземпляр realm с транзакцией async Создание входа в facebook с Android Webview Как определить, когда приложение Android переходит на задний план и возвращается на передний план MapFragment возвращает null Различие может вызывать «java.lang.NullPointerException» Проблема с электронной почтой (отправка гиперссылки по электронной почте) Android: запись не удалась: EPIPE (Broken pipe) Ошибка при записи файла Как использовать аннотацию @Contract Android 4.2.2 делает иконку и заголовок значка программы активным, как будто часть одной и той же кнопки Неавторизованное беспроводное устройство ADB Как сделать одноранговое соединение android равным без использования промежуточного сервера?

Как выровнять текст по вертикали?

Цель: Android> = 1.6 на чистом холсте.

Предположим, что я хочу написать функцию, которая будет рисовать большой красный прямоугольник (ширина, высота), а затем нарисовать черный текст Hello World внутри. Я хочу, чтобы текст визуально находился в центре прямоугольника. Так давайте попробуем:

void drawHelloRectangle(Canvas c, int topLeftX, int topLeftY, int width, int height) { Paint mPaint = new Paint(); // height of 'Hello World'; height*0.7 looks good int fontHeight = (int)(height*0.7); mPaint.setColor(COLOR_RED); mPaint.setStyle(Style.FILL); c.drawRect( topLeftX, topLeftY, topLeftX+width, topLeftY+height, mPaint); mPaint.setTextSize(fontHeight); mPaint.setColor(COLOR_BLACK); mPaint.setTextAlign(Align.CENTER); c.drawText( "Hello World", topLeftX+width/2, ????, mPaint); } 

Теперь я не знаю, что добавить в аргумент drawText, помеченный ???? , Т.е. я не знаю, как вертикально выравнивать текст.

Что-то вроде

???? = TopLeftY + height / 2 + fontHeight / 2 – fontHeight / 8;

Похоже, работает более или менее нормально, но должен быть лучший способ.

Solutions Collecting From Web of "Как выровнять текст по вертикали?"

Пример для центра на cx и cy :

 private final Rect textBounds = new Rect(); //don't new this up in a draw method public void drawTextCentred(Canvas canvas, Paint paint, String text, float cx, float cy){ paint.getTextBounds(text, 0, text.length(), textBounds); canvas.drawText(text, cx - textBounds.exactCenterX(), cy - textBounds.exactCenterY(), paint); } 

Почему height()/2f работает одинаково?

exactCentre() = (top + bottom) / 2f .

height()/2f = (bottom - top) / 2f

Это приведет только к тому же результату, когда top равен 0 . Это может иметь место для некоторых шрифтов любого размера или других шрифтов в некоторых размерах, но не для всех шрифтов любого размера.

 textY = topLeftY + height/2 - (mPaint.descent() + mPaint.ascent()) / 2 

Расстояние от «базовой линии» до «центра» должно быть -(mPaint.descent() + mPaint.ascent()) / 2

На основе ответа Steelbytes обновленный код будет выглядеть примерно так:

 void drawHelloRectangle(Canvas c, int topLeftX, int topLeftY, int width, int height) { Paint mPaint = new Paint(); // height of 'Hello World'; height*0.7 looks good int fontHeight = (int)(height*0.7); mPaint.setColor(COLOR_RED); mPaint.setStyle(Style.FILL); c.drawRect( topLeftX, topLeftY, topLeftX+width, topLeftY+height, mPaint); mPaint.setTextSize(fontHeight); mPaint.setColor(COLOR_BLACK); mPaint.setTextAlign(Align.CENTER); String textToDraw = new String("Hello World"); Rect bounds = new Rect(); mPaint.getTextBounds(textToDraw, 0, textToDraw.length(), bounds); c.drawText(textToDraw, topLeftX+width/2, topLeftY+height/2+(bounds.bottom-bounds.top)/2, mPaint); } 

Поскольку текст чертежа в Y означает, что исходный текст текста будет заканчиваться Y пикселями вниз от начала координат, то, что вам нужно сделать, когда вы хотите центрировать текст в прямоугольнике (width, height) является:

 paint.setTextAlign(Paint.Align.CENTER); // centers horizontally canvas.drawText(text, width / 2, (height - paint.ascent()) / 2, paint); 

Имейте в виду, что восхождение отрицательное (что объясняет знак минус).

Это не учитывает спуск, что обычно является тем, что вы хотите (восхождение, как правило, высоты шапки выше базовой линии).

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

 public static PointF getTextCenterToDraw(String text, RectF region, Paint paint) { Rect textBounds = new Rect(); paint.getTextBounds(text, 0, text.length(), textBounds); float x = region.centerX() - textBounds.width() * 0.4f; float y = region.centerY() + textBounds.height() * 0.4f; return new PointF(x, y); } 

Применение:

 PointF p = getTextCenterToDraw(text, rect, paint); canvas.drawText(text, px, py, paint);