自定義view 系列二 text相關方法

雖然介紹的是有關draw text的相關方法,但是一些屬性設置還是通過Paint 來設定,畢竟text還是paint  畫出來的。

一、paint的方法、canvas.drawText方法以及Typeface的使用

1. paint的方法介紹

        Paint.Style.FILL:填充內部
        Paint.Style.FILL_AND_STROKE  :填充內部和描邊
        Paint.Style.STROKE  :描邊*/
        setUnderlineText(true):設置下劃線
        setStrikeThruText(true):設置刪除線
        setTextSkewX(float  skewX):傾斜度, - 左,+右
        setTextScaleX(float scaleX):整數爲水平伸長
        //drawText  以及樣式
        mPaint.setStyle(Paint.Style.STROKE);       //字體中間不填充
        canvas.drawText("一篇詩,一斗酒,一曲長歌,一劍天涯", 100, 100, mPaint);

        mPaint.setStyle(Paint.Style.FILL);         //字體填充
        canvas.drawText("一篇詩,一斗酒,一曲長歌,一劍天涯", 100, 250, mPaint);

        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);  //字體填充
        canvas.drawText("一篇詩,一斗酒,一曲長歌,一劍天涯", 100, 400, mPaint);

        mPaint.setUnderlineText(true);   //設置下劃線
        mPaint.setStrikeThruText(true);  //設置刪除線
        mPaint.setTextSkewX((float) -0.25);  //傾斜度  - 左, + 右
        canvas.drawText("一篇詩,一斗酒,一曲長歌,一劍天涯", 100, 550, mPaint);

        mPaint.setTextScaleX(2);   //水平拉伸原來的2倍(上一次樣式的2倍)
        mPaint.setColor(Color.BLUE);
        canvas.drawText("一篇詩,一斗酒,一曲長歌,一劍天涯", 1, 5, 100, 700, mPaint);  //  0開始不包含5   篇詩,一
效果圖如下




2. canvas drawText

public void drawText(String text, float x, float y, Paint paint)
根據x, y座標開始繪製第一個字

public void drawText(String text, int start, int end, float x, float y, Paint paint)
根據x, y座標繪製,並且使用start end來截取text中的文字

public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
根據path路徑進行繪製
 float hOffset  : 與路徑起始點的水平偏移距離
 float vOffset  : 與路徑中心的垂直偏移量

public void drawPosText(String text, float[] pos, Paint paint)
根據pos提供的點(2個一組),進行繪製
注意:pos中的點數不能小於text的長度,不然會報java.lang.IndexOutOfBoundsException;所以在使用時要注意
ps: 這邊列舉了主要的方法,還有其他方法與上方的區別是傳入的字符串類型不一樣,可能是char[], CharSequence, string
        float[] pos = {80, 80, 200, 1050, 250, 80, 234, 456, 240, 300, 400, 500, 900, 600};
        canvas.drawPosText("但願長醉不復醒", pos, mPaint);   //根據位置來寫每個字
        //canvas.drawPosText("一篇詩,一斗酒,一曲長歌,一劍天涯".toCharArray(), 2, 4, pos, mPaint);
        mPaint.setColor(Color.GREEN);
        //drawOnPath
        RectF mRectF = new RectF(100, 100, 600, 500);
        Path mPath = new Path();
        mPath.addOval(mRectF, Path.Direction.CW); //順時針
        canvas.drawTextOnPath("一篇詩,一斗酒,一曲長歌,一劍天涯", mPath, 0, 0, mPaint);

效果圖如下:


3. Typeface 的使用

Typeface 是用來設置字體樣式的,除了系統的字體,還有自定義的.ttf的字體使用
創建Typeface:  可指定系統或自定義的字體進行設置
        Typeface create(String familyName, int style) //直接通過指定字體名來加載系統中自帶的文字樣式
        Typeface create(Typeface family, int style)     //通過其它Typeface變量來構建文字樣式
        Typeface createFromAsset(AssetManager mgr, String path) //通過從Asset中獲取外部字體來顯示字體樣式
        Typeface createFromFile(String path)//直接從路徑創建
        Typeface createFromFile(File path)//從外部路徑來創建字體樣式
        Typeface defaultFromStyle(int style)//創建默認字體


        上面的幾個個參數會用到Style變量,Style的枚舉值如下:
        Typeface.NORMAL  //正常體
        Typeface.BOLD //粗體
        Typeface.ITALIC //斜體
        Typeface.BOLD_ITALIC //粗斜體

        Typeface font = Typeface.create("宋體", Typeface.NORMAL);
        mPaint.setTypeface(font);
        mPaint.setTextSize(100);
        canvas.drawText("Aa", 80, 200, mPaint);

        Typeface font1 = Typeface.createFromAsset(getContext().getAssets(), "DancingScript-Bold.ttf");
        mPaint.setTypeface(font1);
        canvas.drawText("Aa", 80, 400, mPaint);

效果圖如下:




二、drawText中的須知特點

當我們使用public void drawText(String text, float x, float y, Paint paint)時,實驗我們設置爲(0,0),此時我們是看不到文字的;
這是因爲,設置的x, y 其實是設置的一條基線,x,y 爲頂點,y爲高的直線,就像小時候寫英語單詞的4線格的第三條,而不是左上角的頂點。
爲了能夠寫好文字,android中提供瞭如下幾條線:

        baseline: 基線,開發這自己定義的
        ascent:   系統建議的,繪製單個字符時,字符應當的最高高度所在線
        descent:  系統建議的,繪製單個字符時,字符應當的最低高度所在線
        top:      可繪製的最高高度所在線
        bottom:   可繪製的最低高度所在線

1. 畫一條基線

setTextAlign,指定點在文字的相對位置
下面代碼表示的是在(300, 500)繪製的文字以及一條直線
Paint paint_line = createPaint(Color.RED, Paint.Style.STROKE, 5);
        canvas.drawColor(Color.BLACK);
        int x = 300;
        int y = 500;
        canvas.drawLine(x, y, 1800, 500, paint_line);
//        paint_text.setTextAlign(Paint.Align.CENTER); //文字的中間位置在指定點
        paint_text.setTextAlign(Paint.Align.LEFT); //默認情況,文字的左邊在指定點
//        paint_text.setTextAlign(Paint.Align.RIGHT);  //以文字的右邊在指定點
        canvas.drawText("HaaaAgfj", 300, 500, paint_text);
運行結果如下: 指定點在文字的左側,並且紅色就是基線



2. 如何判斷其他線的位置

基線baseline是由drawText的x, y 座標決定的。
當baseline 位置決定後,其他4條線也就可以計算出來。
android 提供了Paint.FontMetrics text_meterics = paint_text.getFontMetrics();  
public static class FontMetrics {
        public float ascent;
        public float bottom;
        public float descent;
        public float leading;
        public float top;
        public FontMetrics() {
            throw new RuntimeException("Stub!");
        }
    }

所以我們獲得的基線是有正有負的,因爲他的計算方法如下。
ascent = ascent線的y座標 - baseline線的y座標;
descent = descent線的y座標 - baseline線的y座標;
top = top線的y座標 - baseline線的y座標;
bottom = bottom線的y座標 - baseline線的y座標;

根據上面公式,幾條線的y座標就能計算得出,那麼下面我們畫出其他幾條線:
Paint.FontMetrics text_meterics = paint_text.getFontMetrics();
        int top = (int) (y + text_meterics.top);
        int ascent = (int) (y + text_meterics.ascent);
        int descent = (int) (y + text_meterics.descent);
        int bottom = (int) (y + text_meterics.bottom);


        canvas.drawLine(x, top, 1800, top, paint_line);
        canvas.drawLine(x, ascent, 1800, ascent, paint_line);
        canvas.drawLine(x, bottom, 1800, bottom, paint_line);
        paint_line.setColor(Color.BLUE);
        canvas.drawLine(x, descent, 1800, descent, paint_line);
其中bottom和descent的距離比較近,效果圖如下:





3. 繪製文字矩形

1. 繪製文字的區域 
    上面計算出top 以及 bottom 這裏只要計算出文字的寬度Paint.measureText.
        int textWidth = (int) paint_text.measureText("HaaaAgfj");
        Rect mRect = new Rect(x, top, x + textWidth, bottom);
        canvas.drawRect(mRect, paint_line);

2. 繪製文字的當前區域
可通過getTextBounds獲得在基線y=0時候的矩形各點座標
        Paint paint_rect = createPaint(Color.BLUE, Paint.Style.STROKE, 5);
        Rect minRect = new Rect();
        paint_rect.getTextBounds("HaaaAgfj",0,"HaaaAgfj".length(),minRect); //paint.getTextBounds()得到基線爲y=0的最小矩形的各點座標
        minRect.top = y + minRect.top;
        minRect.bottom = y + minRect.bottom;
        minRect.left = x;
        minRect.right = x + textWidth;
        canvas.drawRect(minRect,paint_rect);
效果如下:



發佈了37 篇原創文章 · 獲贊 10 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章