在 Canvas 上繪製多行文字時,若直接呼叫 drawString 超出螢幕寬度會被截斷。需依字體度量將長字串切分為適合螢幕的行陣列。中英混排時,英文單詞不應在字母中間斷行,中文字可逐字斷行。
Font.stringWidth(substring) 量測子字串寬度。Vector(或 ArrayList)回傳。public Vector parseString(String str) {
str = str.trim();
if (str.length() == 0) return null;
final char NEWLINE = '\n';
int screenWidth = getWidth() - 20; // 留邊距
int lastBreak = 0; // 上一個合法斷行位置
int lineStart = 0; // 當前行起始索引
boolean inWord = false; // 是否在英文單詞中
Vector lines = new Vector();
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
boolean isLetter = ch < 256; // 簡易判斷 ASCII 字元
boolean isNewline = (ch == NEWLINE);
// 更新合法斷行點
if ((ch == ' ' && isLetter) || isNewline || !isLetter) {
lastBreak = i;
}
// 非最後一字元:檢查是否需換行
if (i < str.length() - 1) {
String test = str.substring(lineStart, i + 1);
if (font.stringWidth(test) > screenWidth || isNewline) {
// 在 lastBreak 切分
lines.addElement(str.substring(lineStart, lastBreak));
// 下一行起始:若是單詞中斷行,跳過空格
lineStart = isLetter ? lastBreak + 1 : lastBreak;
}
} else {
// 最後一字元:收尾
lines.addElement(str.substring(lineStart));
}
}
return lines;
}
ch < 256 視為英文字元(含標點),反之為中文字元。中文字元視為獨立斷行點,無需空格。\n 無條件在該處切分。stringWidth 呼叫較重,實際專案可快取字元寬度或預先計算字串寬度陣列。// 在 Canvas 子類別中
private Vector textLines;
private String longText = "這是一段很長的中英文混排文字 This is a long English sentence.";
protected void initText() {
textLines = parseString(longText);
}
protected void paint(Graphics g) {
g.setColor(0xFFFFFF); g.fillRect(0,0,getWidth(),getHeight());
g.setColor(0x000000);
int y = 10;
int lineH = g.getFont().getHeight() + 2;
for (int i=0; i