代碼對比
// 方式一:從現有 TextView 獲取 (複製屬性)
TextPaint textPaint = textView.getPaint();
// 方式二:創建全新對象 (默認屬性)
TextPaint textPaint = new TextPaint();
核心區別
| 特性 | getPaint() | new TextPaint() |
| 來源 | 現有 View 的畫筆引用 | 全新獨立對象 |
| 屬性繼承 | 自動包含文字大小、顏色、字體等 | 默認值 (黑色、12sp、無防銳利化) |
| 修改影響 | 會影響原 View 繪製 (同一對象) | 不影響任何現有 View |
| 適用場景 | 測量文本、基於現有樣式微調 | 完全自定義繪製、Canvas 畫文本 |
原理深度解析
// TextView 源碼片段
private TextPaint mTextPaint;
public TextPaint getPaint() {
return mTextPaint; // 直接返回內部引用
}
getPaint() 返回的是 TextView 內部用於繪製的同一個對象引用
- 修改返回的
TextPaint 會直接影響 TextView 後續繪製
- 若需隔離,應複製屬性:
TextPaint tp = new TextPaint(textView.getPaint());
實戰應用場景
1. 精確測量文本寬高 (推薦 getPaint)
TextPaint paint = textView.getPaint();
float width = paint.measureText("測試文本");
Paint.FontMetrics fm = paint.getFontMetrics();
float height = fm.descent - fm.ascent;
2. 自定義 View 繪製文本 (推薦 new TextPaint)
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setTextSize(32);
canvas.drawText("自定義繪製", 100, 100, paint);
}
3. 基於現有樣式微調 (複製後修改)
TextPaint paint = new TextPaint(textView.getPaint()); // 複製屬性
paint.setUnderlineText(true); // 添加下劃線
paint.setTextScaleX(1.2f); // 字符間距
// 用於 StaticLayout 等佈局計算
最佳實踐建議
- 測量/計算佈局 →
getPaint() (保持樣式一致)
- Canvas 繪製/完全自定義 →
new TextPaint()
3. 需修改但不影響原 View → new TextPaint(view.getPaint()) 複製構造
4. 及時回收:Paint 對象輕量,但頻繁創建建議復用