轉載請注明出處: 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. 音樂播放器類,桌面歌詞滾動(可帶顏色)
