นอกเหนือจากการวาดข้อความหลายบรรทัดแล้วอาจมีปัญหากับการกำหนดขอบเขตข้อความหลายบรรทัด (เช่นเพื่อจัดแนวบนผ้าใบ)
ค่าเริ่มต้นpaint.getTextBounds()
จะไม่ทำงานในกรณีนี้เนื่องจากจะวัดบรรทัดเดียว
เพื่อความสะดวกฉันสร้างฟังก์ชั่นส่วนขยาย 2 รายการนี้: อันหนึ่งสำหรับวาดข้อความหลายบรรทัดและอีกอันใช้สำหรับกำหนดขอบเขตข้อความ
private val textBoundsRect = Rect()
/**
* Draws multi-line text on the Canvas with the origin at (x,y), using the specified paint. The origin is interpreted
* based on the Align setting in the paint.
*
* @param text The text to be drawn
* @param x The x-coordinate of the origin of the text being drawn
* @param y The y-coordinate of the baseline of the text being drawn
* @param paint The paint used for the text (e.g. color, size, style)
*/
fun Canvas.drawTextMultiLine(text: String, x: Float, y: Float, paint: Paint) {
var lineY = y
for (line in text.split("\n")) {
lineY += paint.descent().toInt() - paint.ascent().toInt()
drawText(line, x, lineY, paint)
}
}
/**
* Retrieve the text boundary box, taking into account line breaks [\n] and store to [boundsRect].
*
* Return in bounds (allocated by the caller [boundsRect] or default mutable [textBoundsRect]) the smallest rectangle that
* encloses all of the characters, with an implied origin at (0,0).
*
* @param text string to measure and return its bounds
* @param start index of the first char in the string to measure. By default is 0.
* @param end 1 past the last char in the string to measure. By default is test length.
* @param boundsRect rect to save bounds. Note, you may not supply it. By default, it will apply values to the mutable [textBoundsRect] and return it.
* In this case it will be changed by each new this function call.
*/
fun Paint.getTextBoundsMultiLine(
text: String,
start: Int = 0,
end: Int = text.length,
boundsRect: Rect = textBoundsRect
): Rect {
getTextBounds(text, start, end, boundsRect)
val linesCount = text.split("\n").size
val allLinesHeight = (descent().toInt() - ascent().toInt()) * linesCount
boundsRect.bottom = boundsRect.top + allLinesHeight
return boundsRect
}
ตอนนี้การใช้งานทำได้ง่ายอย่างนั้น: สำหรับการวาดข้อความหลายบรรทัด:
canvas.drawTextMultiLine(text, x, y, yourPaint)
สำหรับการวัดข้อความ:
val bounds = yourPaint.getTextBoundsMultiLine (ข้อความ)
ในกรณีนี้จะวัดข้อความทั้งหมดตั้งแต่ต้นจนจบและด้วยการใช้ค่าเริ่มต้นเมื่อจัดสรรแล้ว (เปลี่ยนแปลงได้) Rect
คุณสามารถเล่นกับการส่งผ่านพารามิเตอร์พิเศษเพื่อความยืดหยุ่นมากขึ้น
Layout
แทนการโทรCanvas.drawText
โดยตรง ถาม & ตอบนี้แสดงวิธีใช้ aStaticLayout
เพื่อวาดข้อความหลายบรรทัด