Gettextbounds в Android
Мы использовали, чтобы найти прямоугольник, который соответствует данному тексту, например, если дать "TESTING" в gettextbounds api, он даст прямоугольник, который соответствует данной строке "TESTING", но любой плз может уточнить, на каком основании рассчитывается длина прямоугольника, будет ли учитываться размер шрифта, если это возможно, я могу проверить, как это?
1) Как я попробовал CharSequence text = getText (); canvas.drawText (text, 0, text.length (), mTextX, mTextY, getPaint ());
Paint pt = new Paint ( );
pt.setTextSize(10);
TextPaint tp = getPaint();
String string = "haa";
Rect currentBounds = new Rect ( );
//this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 32);
tp.getTextBounds((String) text, 0, text.length(), currentBounds );
Log.e ( " ", "Desired Text " +text);
Log.e ( " ", "first Ondraw Left " +currentBounds.left);
Log.e ( " ", "Ondraw Top" +currentBounds.top);
Log.e ( " ", "Ondraw right " +currentBounds.right);
Log.e ( " ", "Ondraw bottom " +currentBounds.bottom);
pt.setTextSize(20);
tp.getTextBounds((String) text, 0, text.length(), currentBounds );
Log.e ( "", "Desired Text " +text);
Log.e ( " ", "Second Ondraw Left " +currentBounds.left);
Log.e ( " ", "Ondraw Top" +currentBounds.top);
Log.e ( " ", "Ondraw right " +currentBounds.right);
Log.e ( "Nrace ", "Ondraw bottom " +currentBounds.bottom);
2) Второй способ я попробовал
TextPaint tp = getPaint();
String string = "haa";
Rect currentBounds = new Rect ( );
this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 32);
tp.getTextBounds(string, 0, string.length(), currentBounds );
Log.e ( " ", "first Left " +currentBounds.left);
Log.e ( " ", "Top" +currentBounds.top);
Log.e ( " ", "right " +currentBounds.right);
Log.e ( " ", "bottom " +currentBounds.bottom);
this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 10);
tp.getTextBounds(string, 0, string.length(), currentBounds );
Log.e ( " ", "Sefond Left " +currentBounds.left);
Log.e ( " ", "Top" +currentBounds.top);
Log.e ( " ", "right " +currentBounds.right);
Log.e ( "", "bottom " +currentBounds.bottom);
В вышеупомянутых двух методах я пытаюсь найти различный размер прямоугольника для данного размера текста. Если это не хороший способ, пожалуйста, посоветуйте мне, опубликовав несколько примеров кодов. Проще говоря, я должен найти различный прямоугольник, который соответствует тексту "ТЕСТИРОВАНИЕ" для различного размера шрифта.
Заранее спасибо.
4 ответа
Я нахожу эту часть API довольно запутанной, однако, я думаю, я почти понял, как она работает. Вызов getTextBounds() возвращает наименьший прямоугольник, который будет содержать все символы, нарисованные последующим вызовом drawText() с x=0 и y=0. Об этом говорится в нескольких разных словах об API. Все, что есть в Paint и может повлиять на внешний вид текста, учитывается. Вот пример:
Rect bounds = new Rect();
Paint paint = new Paint();
paint.setTextAlign(Align.LEFT);
paint.setTypeface(typeface);
paint.setTextSize(textSize);
paint.getTextBounds(text, 0, text.length(), bounds);
Причина, по которой прямоугольник имеет такие экзотические координаты, заключается в том, что когда вы рисуете текст с помощью drawText(), начало координат, к которому относятся x и y, зависит от типографских свойств выбранной вами краски. Например, у относится к базовой линии, которая не выше и не ниже шрифта, но обычно наносит удар где-то посередине. По этой причине прямоугольник границ будет иметь (обычно) отрицательную вершину и положительное дно. Отрицательный верх означает, что верх текста находится выше базовой линии (y уменьшается при увеличении), в то время как положительный низ означает, что нижняя часть текста находится ниже базовой линии (y увеличивается при снижении). Интересно отметить, что при измерении строки, такой как "Привет", нижняя часть, скорее всего, будет 0, потому что эти символы не имеют ниже базовой части. Напротив, когда вы измеряете строку типа "Hg", вы, скорее всего, получите положительное дно, потому что история g находится ниже базовой линии. Я не уверен, как оценивается горизонтальное положение.
С этим сказанным, чтобы нарисовать текст, из которого вы вычислили границы, вы можете сделать:
canvas.drawText(text, -bounds.left, -bounds.top, paint);
Это нарисует текст рядом с верхним левым углом холста. Координаты верхнего левого угла (0, 0), поэтому для перемещения текста вам нужно только добавить желаемую величину смещения:
canvas.drawText(text, -bounds.left + yourX, -bounds.top + yourY, paint);
Другой пример: если вы хотите создать растровое изображение, которое содержит текст, и вы хотите вписать точно доступное пространство, вы можете сделать:
Bitmap bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text, -bounds.left, -bounds.top, paint);
Если вы хотите оставить несколько пикселей слева, справа, сверху и снизу, скажем, 2, вы можете сделать:
Bitmap bitmap = Bitmap.createBitmap(bounds.width() + 4, bounds.height() + 4, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text, -bounds.left + 2, -bounds.top + 2, paint);
Есть некоторые нюансы, поэтому лучше один раз увидеть... Красный прямоугольник показывает границы текста, x,y - любые координаты (левой нижней точки границ текста)
Rect textBounds = new Rect();
Paint textPaint = new Paint();
Paint rectPaint = new Paint();
String text = "java m";
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
textPaint.setTextSize(100);
textPaint.getTextBounds(text, 0, text.length(), textBounds);
canvas.drawText(text, x, y, textPaint);
rectPaint.setColor(Color.RED);
rectPaint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
x, // left
y - textBounds.height(), // top
x + textBounds.width(), // right
y, // bottom
rectPaint);
}
text = "Hello Worlds"
text = "java m"
Вот способ, который работает для меня: использовать Paint.measureText(text)
получить text
ширина и Paint.getTextBounds(text, 0, text.length(), bounds)
получить text
высота (height = bounds.height()
)
Мое решение:
class Pos {
public int X;
public int Y;
}
public static void getTextPositionAndRealBound(Paint paint, String text, int x, int y, Pos pos, Rect bound) {
paint.getTextBounds(text, 0, text.length(), bound);
// in X
bound.left = x;
bound.right = (int)(paint.measureText(text) + 0.5); // .5f to 1
// in Y
y = y - bound.top;
bound.top = y;
bound.bottom = bound.height();
// reset the position
pos.X = x;
pos.Y = y;
}
Вы знаете, что X является правильным, а Y находится внизу в координате границы getTextBounds.
Решение может получить позицию и реальную границу текста. Вы можете переместить текст в любую позицию, просто отредактируйте var - pos и используйте его при вызове Canvas.drawText следующим образом:
Pos pos;
Rect bound;
getTextPositionAndRealBound(paint, text, x, y, pos, bound);
canvas.drawText(text, pos.X, pos.Y, paint);
Примечание: спасибо за совет @ToolmakerSteve