Android 使用View繪制文字(DrawText)技術總結


轉載請注明出處: http://www.cnblogs.com/renhui/p/7453534.html

這里的繪制文字不是直接調用TextView.setText(String content)去展示文字內容。而是在View上面通過 canvas.drawText(text, x, y,textPaint) 的方式直接進行文字的繪制。

一、基本的文字繪制方式

canvas.drawText的方式,需要我們計算好要繪制的文字的起始位置,並通過移動畫布的來移動到指定的位置,繪制文字完成后然后再復原畫布的位置。

canvas.translate(x, y); // 挪動canvas的坐標原點
canvas.drawText(text, x, y, tp);
canvas.translate(-x, -y); // 恢復canvas的坐標原點

通過這段代碼,就可以將文字繪制在指定的位置。

但是有時候我們發現,如果需要繪制的內容很多的時候,直接使用 canvas.drawText 存在很大的問題,列舉其中幾個問題如下:

  • 只能在一行進行繪制,不會自動換行。
  • 即使內容里面存在'\n'等換行字符,可是繪制出來的文字還是在一行里面,'\n'字符展示出來的效果僅僅是一個空格。
  • 超出屏幕的內容是看不到的。

那么怎么處理這個問題呢?Android 的API 里面 有一個非常棒的工具類 -- StaticLayout。通過StaticLayout,我們就能夠實現了文本繪制換行處理

二、使用StaticLayout繪制文本

public void onDraw(Canvas canvas){
  super.onDraw(canvas);
  TextPaint tp = new TextPaint();
  tp.setColor(Color.BLUE);
  tp.setStyle(Style.FILL);
  tp.setTextSize(50);
  String message = "8月30日中午,法制晚報·看法新聞記者從中國電信、中國聯通、中國移動獲悉,三大運營商將從9月1日起全面取消手機國內長途費和漫游費(不含港澳台,下同),比原計划的10月1日提前一個月完成。用戶無需申請,自動生效。";
  StaticLayout myStaticLayout = new StaticLayout(message, tp, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
  myStaticLayout.draw(canvas);
  canvas.restore();
}

上面這段代碼就是使用StaticLayout繪制文本的基本使用方式。運行后發現跟TextView的效果是一樣的,通過閱讀android源碼可以發現,其實TextView也是調用StaticLayout來實現換行的。

StaticLayout的構造函數有三個:

public StaticLayout(CharSequence source, // 需要分行的字符串
TextPaint paint, // 畫筆對象
int width, // layout的寬度,字符串超出寬度時自動換行
Layout.Alignment align, // 對齊方式,有ALIGN_CENTER, ALIGN_NORMAL, ALIGN_OPPOSITE 三種
float spacingmult, // 相對行間距,相對字體大小,1.5f表示行間距為1.5倍的字體高度。
float spacingadd, // 在基礎行距上添加多少(實際行間距等於兩者和)
boolean includepad)
public StaticLayout(CharSequence source, // 需要分行的字符串
int bufstart, // 需要分行的字符串從第幾位開始
int bufend, // 需要分行的字符串到哪里結束
TextPaint paint,  // 畫筆對象
int outerwidth, // layout的寬度,字符串超出寬度時自動換行
Layout.Alignment align, // 對齊方式,有ALIGN_CENTER, ALIGN_NORMAL, ALIGN_OPPOSITE 三種
float spacingmult, // 相對行間距,相對字體大小,1.5f表示行間距為1.5倍的字體高度。
float spacingadd, // 在基礎行距上添加多少
boolean includepad)
public StaticLayout(CharSequence source, // 需要分行的字符串
int bufstart,  // 需要分行的字符串從第幾位開始
int bufend, // 需要分行的字符串到哪里結束
TextPaint paint, // 畫筆對象
int outerwidth, // layout的寬度,字符串超出寬度時自動換行。
Layout.Alignment align, // 對齊方式,有ALIGN_CENTER, ALIGN_NORMAL, ALIGN_OPPOSITE 三種。
float spacingmult, // 相對行間距,相對字體大小,1.5f表示行間距為1.5倍的字體高度。
float spacingadd, // 在基礎行距上添加多少
boolean includepad,
TextUtils.TruncateAt ellipsize,
int ellipsizedWidth)

三、使用StaticLayout的情景

我們已經知道,使用StaticLayout可以很好的幫助我們處理文字繪制時的換行問題,那么什么地方我們能夠用到StaticLayout呢?下面我可以列舉幾個例子:

1. 輔助圖文混排的編輯器,生成圖文一體的長圖 -- 需要自定義View繪制的基礎。

2. 音樂播放器類,桌面歌詞滾動(可帶顏色)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM