2010-02-25 33 views
18

Tôi có một điều khiển tùy chỉnh đang thực hiện rất nhiều bản vẽ 2D thẳng đến canvas.Bao gói văn bản dài trên Canvas Android

Một số bản vẽ này là văn bản, vì vậy tôi đang sử dụng phương pháp Canvas.drawText().

Tôi muốn vẽ văn bản trong một số giới hạn - một góc trên cùng bên trái, chiều rộng tối đa nhất định và số dòng tối đa. Sau khi vẽ văn bản, tôi muốn biết có bao nhiêu dòng.

Có chức năng tích hợp để vẽ văn bản trong giới hạn làm việc chia tách hợp lý không?

Nếu không, có công thức chuẩn nào để làm như vậy không?

+0

Xem câu trả lời này cho một ví dụ sử dụng tốt về 'StaticLayout's: http://stackoverflow.com/a/8369690/293280 –

Trả lời

30

Bạn có thể sử dụng lớp android.text.StaticLayout cho việc này; chỉ cần tạo một StaticLayout cho văn bản mong muốn, căn chỉnh, chiều rộng, v.v. và gọi phương thức draw(Canvas) của nó để vẽ lên canvas.

+0

Thật tuyệt vời khi tôi bỏ qua nó – Will

+0

Đây có phải là chỉ dành cho Android không? Còn các nền tảng khác thì sao? –

+0

Tuyệt vời! Bạn sẽ căn giữa văn bản trong canvas như thế nào? –

4

Bạn có thể sử dụng Paint.getTextBounds() để đo kích thước của toàn bộ chuỗi hoặc Paint.getTextWidths() để nhận được chiều rộng của mỗi ký tự. Sau đó chia chuỗi thích hợp trước khi vẽ.

3

Tôi gặp sự cố tương tự. Một trong những giải pháp đầu tiên của tôi là sau.

/** 
    * This function draws the text on the canvas based on the x-, y-position. 
    * If it has to break it into lines it will do it based on the max width 
    * provided. 
    * 
    * @author Alessandro Giusa 
    * @version 0.1, 14.08.2015 
    * @param canvas 
    *   canvas to draw on 
    * @param paint 
    *   paint object 
    * @param x 
    *   x position to draw on canvas 
    * @param y 
    *   start y-position to draw the text. 
    * @param maxWidth 
    *   maximal width for break line calculation 
    * @param text 
    *   text to draw 
    */ 
public static void drawTextAndBreakLine(final Canvas canvas, final Paint paint, 
     final float x, final float y, final float maxWidth, final String text) { 
    String textToDisplay = text; 
    String tempText = ""; 
    char[] chars; 
    float textHeight = paint.descent() - paint.ascent(); 
    float lastY = y; 
    int nextPos = 0; 
    int lengthBeforeBreak = textToDisplay.length(); 
    do { 
     lengthBeforeBreak = textToDisplay.length(); 
     chars = textToDisplay.toCharArray(); 
     nextPos = paint.breakText(chars, 0, chars.length, maxWidth, null); 
     tempText = textToDisplay.substring(0, nextPos); 
     textToDisplay = textToDisplay.substring(nextPos, textToDisplay.length()); 
     canvas.drawText(tempText, x, lastY, paint); 
     lastY += textHeight; 
    } while(nextPos < lengthBeforeBreak); 
} 

gì là mất tích:

  • Không có cơ chế phá vỡ dòng thông minh, vì nó phá vỡ dựa trên maxWidth

Làm thế nào để gọi?

paint.setTextSize(40); 
    paint.setColor(Color.WHITE); 
    paint.setSubpixelText(true); 
    float textHeight = paint.descent() - paint.ascent(); 
    CanvasUtils.drawTextAndBreakLine(canvas, paint, this.left, 
      textHeight, this.displayWidth, this.text); 

Tôi có một lớp tĩnh gọi là CanvasUtils nơi tôi đóng gói những thứ như thế này. Về cơ bản tôi vẽ văn bản trong một hình chữ nhật. Đây là lý do textHeight là chiều cao của văn bản. Nhưng bạn có thể chuyển những gì bạn muốn cho hàm.

Lập trình tốt!

+0

Có điều này làm việc cho tôi nhưng nó buộc từ phải phá vỡ! Có cách nào để khắc phục điều đó không? – Eenvincible

+0

Hey Eenvincible, bạn có nghĩa là những từ đơn? Gạch nối? –

+0

Không nói riêng. những gì xảy ra với mã này là văn bản kết thúc chính xác trong hình chữ nhật nhưng một số từ bị cắt đứt sẽ kết thúc thành các dòng mới với một phần của các từ hiển thị trong một dòng và một phần của từ đó trong dòng tiếp theo. – Eenvincible

Các vấn đề liên quan