這里我們來學(xué)習(xí)一下Paint的使用仍秤,廢話不多說筷凤,開始擼碼
正文
開始我們先要學(xué)習(xí)一下Paint的簡(jiǎn)單使用嘍!
-
設(shè)置畫筆樣式
.setStyle(Paint.Style style) Paint.Style.FILL :填充內(nèi)部 Paint.Style.FILL_AND_STROKE :填充內(nèi)部和描邊 Paint.Style.STROKE :僅描邊 注意STROKE、FILL_OR_STROKE與FILL模式下外輪廓的位置會(huì)擴(kuò)大
-
設(shè)置畫筆寬度
.setStrokeWidth(float width)
-
設(shè)置畫筆是否抗鋸齒
.setAntiAlias(boolean aa)
-
設(shè)置線冒樣式
.setStrokeCap(Paint.Cap cap) Cap.ROUND(圓形線冒)番枚、Cap.SQUARE(方形線冒)忽肛、Paint.Cap.BUTT(無線冒)
-
設(shè)置線段連接處樣式
.setStrokeJoin(Paint.Join join) Join.MITER(結(jié)合處為銳角)村砂、Join.Round(結(jié)合處為圓弧)、Join.BEVEL(結(jié)合處為直線)
-
設(shè)置筆畫的傾斜度
.setStrokeMiter(float miter)
-
清空畫筆復(fù)位
.reset()
-
設(shè)置一個(gè)外來Paint畫筆
.set(Paint src)
-
設(shè)置alpha值麻裁、顏色箍镜、ARGB
.setAlpha(int a) .setColor(int color)
-
獲取與設(shè)置是否使用抗鋸齒功能
.isAntiAlias()
-
設(shè)置抗鋸齒
setAntiAlias(boolean aa)
-
是否使用圖像抖動(dòng)處理
.isDither()
-
設(shè)置圖像抖動(dòng)源祈,會(huì)使繪制出來的圖片顏色更加平滑和飽滿、圖像更加清晰
.setDither(boolean dither)
-
設(shè)置繪制路徑的效果
.setPathEffect(PathEffect effect) CornerPathEffect——圓形拐角效果 DashPathEffect——虛線效果 例 //畫同一條線段,偏移值為15 paint.setPathEffect(new DashPathEffect(new float[]{20,10,50,100},15)); intervals[]:表示組成虛線的各個(gè)線段的長(zhǎng)度色迂;整條虛線就是由intervals[]中這些基本線段循環(huán)組成的香缺。比如,我們定義new float[] {20,10}歇僧;那這個(gè)虛線段就是由兩段線段組成的图张,第一個(gè)可見的線段長(zhǎng)為20,每二個(gè)線段不可見诈悍,長(zhǎng)度為10祸轮; phase: 開始繪制的偏移值 ComposePathEffect ComposePathEffect先應(yīng)用圓角特效,再應(yīng)用虛線特效 SumPathEffect 將生成的兩條特效路徑合并
-
設(shè)置圖形重疊時(shí)的處理方式
.setXfermode(Xfermode xfermode)
-
設(shè)置MaskFilter,可以用不同的MaskFilter實(shí)現(xiàn)濾鏡的效果
.setMaskFilter(MaskFilter maskfilter)
-
設(shè)置顏色過濾器侥钳,可以在繪制顏色時(shí)實(shí)現(xiàn)不用顏色的變換效果
.setColorFilter(ColorFilter colorfilter)
-
設(shè)置圖像效果适袜,使用Shader可以繪制出各種漸變效果
.setShader(Shader shader)
-
在圖形下面設(shè)置陰影層,產(chǎn)生陰影效果
.setShadowLayer(float radius ,float dx,float dy,int color)
radius為陰影的角度舷夺,dx和dy為陰影在x軸和y軸上的距離苦酱,color為陰影的顏色 -
獲取字符行間距
.getFontSpacing()
-
設(shè)置和獲取字符間距
.setLetterSpacing(float letterSpacing) .getLetterSpacing()
-
是否有下劃線和設(shè)置下劃線
.isUnderlineText() .setUnderlineText(boolean underlineText)
-
獲取與設(shè)置是否有文本刪除線
.isStrikeThruText() .setStrikeThruText(boolean strikeThruText)
-
獲取與設(shè)置文字大小
.getTextSize() .setTextSize(float textSize) 注意:Paint.setTextSize傳入的單位是px,TextView.setTextSize傳入的單位是sp
-
獲取與設(shè)置字體類型
.getTypeface() .setTypeface(Typeface typeface) Android默認(rèn)有四種字體樣式:BOLD(加粗)给猾、BOLD_ITALIC(加粗并傾斜)疫萤、ITALIC(傾斜)、NORMAL(正常)敢伸,我們也可以通過Typeface類來自定義個(gè)性化字體扯饶。
-
獲取與設(shè)置文字傾斜
.getTextSkewX() .setTextSkewX(float skewX) 官方推薦值為-0.25,值為負(fù)則右傾池颈,為正則左傾尾序,默認(rèn)值為0。
-
獲取與設(shè)置文本對(duì)齊方式
.getTextAlign() .setTextAlign(Paint.Align align)
-
設(shè)置亞像素饶辙,亞像素就是把兩個(gè)相鄰的兩個(gè)像素之間的距離再細(xì)分蹲诀,再插入一些像素,這些通過程序加入的像素就是亞像素弃揽。在兩個(gè)像素間插入的像素個(gè)數(shù)是通過程序計(jì)算出來的脯爪,一般是插入兩個(gè)、三個(gè)或四個(gè)矿微。所以打開亞像素顯示痕慢,是可以在增強(qiáng)文本顯示清晰度的,但由于插入亞像素是通過程序計(jì)算而來的涌矢,所以會(huì)耗費(fèi)一定的計(jì)算機(jī)性能
.setSubpixelText(boolean subpixelText)
-
動(dòng)態(tài)折斷或生成一行字符串
breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth)
-
獲取文本的寬高掖举,通過bounds的Rect拿到整型
void getTextBounds(char[] text, int index, int count, Rect bounds) void getTextBounds(String text, int start, int end, Rect bounds)
-
粗略獲取文本的寬度
float measureText(String text) float measureText(CharSequence text, int start, int end) float measureText(String text, int start, int end) float measureText(char[] text, int index, int count)
-
精確計(jì)算文字寬度
int getTextWidths(String text, int start, int end, float[] widths) int getTextWidths(String text, float[] widths) int getTextWidths(CharSequence text, int start, int end, float[] widths) int getTextWidths(char[] text, int index, int count, float[] widths)
另外就是文字位置的解析,先了解一下FontMetrics的top娜庇,ascent塔次,desent, bottom的屬性
top = top線的y坐標(biāo) - baseline線的y坐標(biāo)
bottom = bottom線的y坐標(biāo) - baseline線的y坐標(biāo)
ascent = ascent線的y坐標(biāo) - baseline線的y坐標(biāo)
desent = desent線的y坐標(biāo) - baseline線的y坐標(biāo)
看圖就能計(jì)算出下面的結(jié)論
baseline = center +(FontMetrics.bottom - FontMetrics.top)/2 - FontMetrics.bottom
知道這些我們能做什么方篮,下圖就可以搞出來
分析圖
邊上的曲線可以使用二級(jí)貝塞爾曲線加上半圓來繪制,整體是一個(gè)正五邊形
部分代碼:
private void drawSmallCircleList(Canvas canvas, PointF node, POSITION position) {
Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setColor(Color.parseColor("#888888"));
circlePaint.setStrokeWidth(5);
circlePaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(node.x, node.y, DEFAULT_CIRCLE_R * 1.0f / 3, circlePaint);
PointF beforePoint = node;
for (int i = 0; i < 5; i++) {
float lineDistance = 1.0f / (i + 3) * DEFAULT_CIRCLE_R + DEFAULT_SMALL_CIRCLE_SPACE + 1.0f / (i + 4) * DEFAULT_CIRCLE_R;
PointF circlePoint = null;
if (position == POSITION.LT) { //左上
circlePoint = new PointF(beforePoint.x + lineDistance * 0.5f * (float) Math.pow(3, 0.5), beforePoint.y + lineDistance * 0.5f);
} else if (position == POSITION.LB) {//左下
circlePoint = new PointF(beforePoint.x + lineDistance * 0.5f, beforePoint.y - lineDistance * 0.5f * (float) Math.pow(3, 0.5));
} else if (position == POSITION.RT) {//右上
circlePoint = new PointF(beforePoint.x - lineDistance * 0.5f * (float) Math.pow(3, 0.5), beforePoint.y + lineDistance * 0.5f);
} else {//右下
circlePoint = new PointF(beforePoint.x - lineDistance * 0.5f, beforePoint.y - lineDistance * 0.5f * (float) Math.pow(3, 0.5));
}
canvas.drawCircle(circlePoint.x, circlePoint.y, DEFAULT_CIRCLE_R * 1.0f / (i + 4), circlePaint);//繪制圓形
beforePoint = circlePoint;
}
}