一、創建路徑
canvas中繪制路徑利用:
void drawPath (Path path, Paint paint)
1、直線路徑
void moveTo (float x1, float y1):直線的開始點;即將直線路徑的繪制點定在(x1,y1)的位置;
void lineTo (float x2, float y2):直線的結束點,又是下一次繪制直線路徑的開始點;lineTo()可以一直用;
void close ():如果連續畫了幾條直線,但沒有形成閉環,調用Close()會將路徑首尾點連接起來,形成閉環;
Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStyle(Style.STROKE);//填充樣式改為描邊 paint.setStrokeWidth(5);//設置畫筆寬度 Path path = new Path(); path.moveTo(10, 10); //設定起始點 path.lineTo(10, 100);//第一條直線的終點,也是第二條直線的起點 path.lineTo(300, 100);//畫第二條直線 path.lineTo(500, 100);//第三條直線 path.close();//閉環 canvas.drawPath(path, paint);
2、矩形路徑
void addRect (float left, float top, float right, float bottom, Path.Direction dir)
void addRect (RectF rect, Path.Direction dir)
這里Path類創建矩形路徑的參數與上篇canvas繪制矩形差不多,唯一不同的一點是增加了Path.Direction參數;
Path.Direction有兩個值:
Path.Direction.CCW:是counter-clockwise縮寫,指創建逆時針方向的矩形路徑;
Path.Direction.CW:是clockwise的縮寫,指創建順時針方向的矩形路徑;
//先創建兩個大小一樣的路徑 //第一個逆向生成 Path CCWRectpath = new Path(); RectF rect1 = new RectF(50, 50, 240, 200); CCWRectpath.addRect(rect1, Direction.CCW); //第二個順向生成 Path CWRectpath = new Path(); RectF rect2 = new RectF(290, 50, 480, 200); CWRectpath.addRect(rect2, Direction.CW); //先畫出這兩個路徑 canvas.drawPath(CCWRectpath, paint); canvas.drawPath(CWRectpath, paint);
問:從效果圖中,看不出順時針生成和逆時針生成的任何區別,怎么會沒區別呢?
答:當然沒區別啦,無論正時針還是逆時針,僅僅是生成方式不同而已,矩形就那么大畫出來的路徑矩形當然與矩形一樣大了。
問:那生成方式有什么區別呢?
答:生成方式的區別在於,依據生成方向排版的文字!后面我們會講到文字,文字是可以依據路徑排版的,那文字的行走方向就是依據路徑的生成方向;
//先創建兩個大小一樣的路徑 //第一個逆向生成 Path CCWRectpath = new Path(); RectF rect1 = new RectF(50, 50, 240, 200); CCWRectpath.addRect(rect1, Direction.CCW); //第二個順向生成 Path CWRectpath = new Path(); RectF rect2 = new RectF(290, 50, 480, 200); CWRectpath.addRect(rect2, Direction.CW); //先畫出這兩個路徑 canvas.drawPath(CCWRectpath, paint); canvas.drawPath(CWRectpath, paint); //依據路徑寫出文字 String text="風蕭蕭兮易水寒,壯士一去兮不復返"; paint.setColor(Color.GRAY); paint.setTextSize(35); canvas.drawTextOnPath(text, CCWRectpath, 0, 18, paint);//逆時針生成 canvas.drawTextOnPath(text, CWRectpath, 0, 18, paint);//順時針生成
3、圓角矩形路徑
void addRoundRect (RectF rect, float[] radii, Path.Direction dir)
void addRoundRect (RectF rect, float rx, float ry, Path.Direction dir)
這里有兩個構造函數,部分參數說明如下:
第一個構造函數:可以定制每個角的圓角大小:
float[] radii:必須傳入8個數值,分四組,分別對應每個角所使用的橢圓的橫軸半徑和縱軸半徑,如{x1,y1,x2,y2,x3,y3,x4,y4},其中,x1,y1對應第一個角的(左上角)用來產生圓角的橢圓的橫軸半徑和縱軸半徑,其它類推……
第二個構造函數:只能構建統一圓角大小
float rx:所產生圓角的橢圓的橫軸半徑;
float ry:所產生圓角的橢圓的縱軸半徑;
Path path = new Path(); RectF rect1 = new RectF(50, 50, 240, 200); path.addRoundRect(rect1, 10, 15 , Direction.CCW); RectF rect2 = new RectF(290, 50, 480, 200); float radii[] ={10,15,20,25,30,35,40,45}; path.addRoundRect(rect2, radii, Direction.CCW); canvas.drawPath(path, paint);
4、圓形路徑
void addCircle (float x, float y, float radius, Path.Direction dir)
參數說明:
float x:圓心X軸坐標
float y:圓心Y軸坐標
float radius:圓半徑
Path path = new Path(); path.addCircle(200, 200, 100, Direction.CCW); canvas.drawPath(path, paint);
5、橢圓路徑
void addOval (RectF oval, Path.Direction dir)
參數說明:
RectF oval:生成橢圓所對應的矩形
Path.Direction :生成方式,與矩形一樣,分為順時針與逆時針,意義完全相同,不再重復
Path path = new Path(); RectF rect = new RectF(50, 50, 240, 200); path.addOval(rect, Direction.CCW); canvas.drawPath(path, paint);
6、弧形路徑
void addArc (RectF oval, float startAngle, float sweepAngle)
參數:
RectF oval:弧是橢圓的一部分,這個參數就是生成橢圓所對應的矩形;
float startAngle:開始的角度,X軸正方向為0度
float sweepAngel:持續的度數;
Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStyle(Style.STROKE);//填充樣式改為描邊 paint.setStrokeWidth(5);//設置畫筆寬度 Path path = new Path(); RectF rect = new RectF(50, 50, 240, 200); path.addArc(rect, 0, 100); canvas.drawPath(path, paint);//畫出路徑
二、文字
1、Paint相關設置
//普通設置 paint.setStrokeWidth (5);//設置畫筆寬度 paint.setAntiAlias(true); //指定是否使用抗鋸齒功能,如果使用,會使繪圖速度變慢 paint.setStyle(Paint.Style.FILL);//繪圖樣式,對於設文字和幾何圖形都有效 paint.setTextAlign(Align.CENTER);//設置文字對齊方式,取值:align.CENTER、align.LEFT或align.RIGHT paint.setTextSize(12);//設置文字大小 //樣式設置 paint.setFakeBoldText(true);//設置是否為粗體文字 paint.setUnderlineText(true);//設置下划線 paint.setTextSkewX((float) -0.25);//設置字體水平傾斜度,普通斜體字是-0.25 paint.setStrikeThruText(true);//設置帶有刪除線效果 //其它設置 paint.setTextScaleX(2);//只會將水平方向拉伸,高度不會變
示例1:繪圖樣式的區別:
Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStrokeWidth (5);//設置畫筆寬度 paint.setAntiAlias(true); //指定是否使用抗鋸齒功能,如果使用,會使繪圖速度變慢 paint.setTextSize(80);//設置文字大小 //繪圖樣式,設置為填充 paint.setStyle(Paint.Style.FILL); canvas.drawText("歡迎光臨Harvic的博客", 10,100, paint); //繪圖樣式設置為描邊 paint.setStyle(Paint.Style.STROKE); canvas.drawText("歡迎光臨Harvic的博客", 10,200, paint); //繪圖樣式設置為填充且描邊 paint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawText("歡迎光臨Harvic的博客", 10,300, paint);
示例二:文字樣式設置及傾斜度正負區別
Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStrokeWidth (5);//設置畫筆寬度 paint.setAntiAlias(true); //指定是否使用抗鋸齒功能,如果使用,會使繪圖速度變慢 paint.setTextSize(80);//設置文字大小 paint.setStyle(Paint.Style.FILL);//繪圖樣式,設置為填充 //樣式設置 paint.setFakeBoldText(true);//設置是否為粗體文字 paint.setUnderlineText(true);//設置下划線 paint.setStrikeThruText(true);//設置帶有刪除線效果 //設置字體水平傾斜度,普通斜體字是-0.25,可見往右斜 paint.setTextSkewX((float) -0.25); canvas.drawText("歡迎光臨Harvic的博客", 10,100, paint); //水平傾斜度設置為:0.25,往左斜 paint.setTextSkewX((float) 0.25); canvas.drawText("歡迎光臨Harvic的博客", 10,200, paint);
示例三:水平拉伸設置( paint.setTextScaleX(2);)
寫三行字,第一行,水平未拉伸的字體;第二行,水平拉伸兩倍的字體;第三行,水平未拉伸和水平拉伸兩部的字體寫在一起,可以發現,僅是水平方向拉伸,高度並未改變;
Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStrokeWidth (5);//設置畫筆寬度 paint.setAntiAlias(true); //指定是否使用抗鋸齒功能,如果使用,會使繪圖速度變慢 paint.setTextSize(80);//設置文字大小 paint.setStyle(Paint.Style.FILL);//繪圖樣式,設置為填充 //變通樣式字體 canvas.drawText("歡迎光臨Harvic的博客", 10,100, paint); //水平方向拉伸兩倍 paint.setTextScaleX(2);//只會將水平方向拉伸,高度不會變 canvas.drawText("歡迎光臨Harvic的博客", 10,200, paint); //寫在同一位置,不同顏色,看下高度是否看的不變 paint.setTextScaleX(1);//先還原拉伸效果 canvas.drawText("歡迎光臨Harvic的博客", 10,300, paint); paint.setColor(Color.GREEN); paint.setTextScaleX(2);//重新設置拉伸效果 canvas.drawText("歡迎光臨Harvic的博客", 10,300, paint);
2、canvas繪圖方式
(1)、普通水平繪制
構造函數:
void drawText (String text, float x, float y, Paint paint)
void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
void drawText (String text, int start, int end, float x, float y, Paint paint)
void drawText (char[] text, int index, int count, float x, float y, Paint paint)
說明:
第一個構造函數:最普通簡單的構造函數;
第三、四個構造函數:實現截取一部分字體給圖;
第二個構造函數:最強大,因為傳入的可以是charSequence類型字體,所以可以實現繪制帶圖片的擴展文字(待續),而且還能截取一部分繪制
這幾個函數就不再多說了,很簡單,前面我們也一直在用第一個構造函數,文字截取一般用不到,我也不多說了,浪費時間,可能大家看到有個構造函數中,可以傳入charSequence類型的字符串,charSequence是可以利用spannableString來構造有圖片的字符串的,那這里是不是可以畫出帶有圖片的字符串來呢 ,我想多了,實際證明,canvas畫圖是不支持Span替換的。所以這里的charSequence跟普通的String沒有任何區別的。
(2)、指定個個文字位置
void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)
void drawPosText (String text, float[] pos, Paint paint)
說明:
第一個構造函數:實現截取一部分文字繪制;
參數說明:
char[] text:要繪制的文字數組
int index::第一個要繪制的文字的索引
int count:要繪制的文字的個數,用來算最后一個文字的位置,從第一個繪制的文字開始算起
float[] pos:每個字體的位置,同樣兩兩一組,如{x1,y1,x2,y2,x3,y3……}
Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStrokeWidth (5);//設置畫筆寬度 paint.setAntiAlias(true); //指定是否使用抗鋸齒功能,如果使用,會使繪圖速度變慢 paint.setTextSize(80);//設置文字大小 paint.setStyle(Paint.Style.FILL);//繪圖樣式,設置為填充 float []pos=new float[]{80,100, 80,200, 80,300, 80,400}; canvas.drawPosText("畫圖示例", pos, paint);//兩個構造函數
(3)、沿路徑繪制
void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)
參數說明:
有關截取部分字體繪制相關參數(index,count),沒難度,就不再講了,下面首重講hOffset、vOffset
float hOffset : 與路徑起始點的水平偏移距離
float vOffset : 與路徑中心的垂直偏移量
Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStrokeWidth (5);//設置畫筆寬度 paint.setAntiAlias(true); //指定是否使用抗鋸齒功能,如果使用,會使繪圖速度變慢 paint.setTextSize(45);//設置文字大小 paint.setStyle(Paint.Style.STROKE);//繪圖樣式,設置為填充 String string="風蕭蕭兮易水寒,壯士一去兮不復返"; //先創建兩個相同的圓形路徑,並先畫出兩個路徑原圖 Path circlePath=new Path(); circlePath.addCircle(220,200, 180, Path.Direction.CCW);//逆向繪制,還記得嗎,上篇講過的 canvas.drawPath(circlePath, paint);//繪制出路徑原形 Path circlePath2=new Path(); circlePath2.addCircle(750,200, 180, Path.Direction.CCW); canvas.drawPath(circlePath2, paint);//繪制出路徑原形 paint.setColor(Color.GREEN); //hoffset、voffset參數值全部設為0,看原始狀態是怎樣的 canvas.drawTextOnPath(string, circlePath, 0, 0, paint); //第二個路徑,改變hoffset、voffset參數值 canvas.drawTextOnPath(string, circlePath2, 80, 30, paint);
3、字體樣式設置(Typeface)
在Paint中設置字體樣式:
paint.setTypeface(typeface);
Typeface相關
概述:Typeface是專門用來設置字體樣式的,通過paint.setTypeface()來指定。可以指定系統中的字體樣式,也可以指定自定義的樣式文件中獲取。要構建Typeface時,可以指定所用樣式的正常體、斜體、粗體等,如果指定樣式中,沒有相關文字的樣式就會用系統默認的樣式來顯示,一般默認是宋體。
創建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 //粗斜體
(1)、使用系統中的字體
從上面創建Typeface的所有函數中可知,使用系統中自帶的字體有下面兩種方式來構造Typeface:
Typeface defaultFromStyle(int style)//創建默認字體
Typeface create(String familyName, int style) //直接通過指定字體名來加載系統中自帶的文字樣式
其實,第一個僅僅是使用系統默認的樣式來繪制字體,基本沒有可指定性,就不再講了,使用起來難度也不大,下面只以第二個構造函數為例,指定宋體繪制:
//使用系統自帶字體繪制 Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStrokeWidth (5);//設置畫筆寬度 paint.setAntiAlias(true); //指定是否使用抗鋸齒功能,如果使用,會使繪圖速度變慢 paint.setTextSize(60);//設置文字大小 paint.setStyle(Paint.Style.STROKE);//繪圖樣式,設置為填充 String familyName = "宋體"; Typeface font = Typeface.create(familyName,Typeface.NORMAL); paint.setTypeface(font); canvas.drawText("歡迎光臨Harvic的博客",10,100, paint);
2、自字義字體
自定義字體的話,我們就需要從外部字體文件加載我們所需要的字形的,從外部文件加載字形所使用的Typeface構造函數如下面三個:
Typeface createFromAsset(AssetManager mgr, String path) //通過從Asset中獲取外部字體來顯示字體樣式
Typeface createFromFile(String path)//直接從路徑創建
Typeface createFromFile(File path)//從外部路徑來創建字體樣式
后面兩個從路徑加載難度不大,而我們一般也不會用到,這里我們說說從Asset文件中加載;
首先在Asset下建一個文件夾,命名為fonts,然后將字體文件jian_luobo.ttf 放入其中
//自定義字體,,,迷你簡羅卜 Paint paint=new Paint(); paint.setColor(Color.RED); //設置畫筆顏色 paint.setStrokeWidth (5);//設置畫筆寬度 paint.setAntiAlias(true); //指定是否使用抗鋸齒功能,如果使用,會使繪圖速度變慢 paint.setTextSize(60);//設置文字大小 paint.setStyle(Paint.Style.FILL);//繪圖樣式,設置為填充 AssetManager mgr=m_context.getAssets();//得到AssetManager Typeface typeface=Typeface.createFromAsset(mgr, "fonts/jian_luobo.ttf");//根據路徑得到Typeface paint.setTypeface(typeface); Log.v("msg",typeface.toString()); canvas.drawText("歡迎光臨Harvic的博客",10,100, paint);//兩個構造函數