轉載請以鏈接形式標明出處:
本文出自:103style的博客
setStrokeCap
設置畫筆的線冒樣式:
- Paint.Cap.BUTT:無
- Paint.Cap.SQUARE:方形
- Paint.Cap.ROUND: 半圓形
注意: Paint.Cap.ROUND、Paint.Cap.SQUARE 會在線長度的基礎上首尾添加一個通過 setStrokeWidth 設置的寬度。
示例如下:依次爲 無設置、Paint.Cap.BUTT、Paint.Cap.SQUARE、Paint.Cap.ROUND。
可以看到 ROUND 和 SQUARE 樣式的明顯長一點。
public StrokeJoinCapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setStrokeWidth(60);
paint.setStyle(Paint.Style.STROKE);
paint.setDither(true);
paint.setColor(Color.RED);
path = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int temp = 120;
canvas.drawLine(temp, temp, getMeasuredWidth() - temp, temp, paint);
paint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawLine(temp, temp * 2, getMeasuredWidth() - temp, temp * 2, paint);
paint.setStrokeCap(Paint.Cap.SQUARE);
canvas.drawLine(temp, temp * 3, getMeasuredWidth() - temp, temp * 3, paint);
paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(temp, temp * 4, getMeasuredWidth() - temp, temp * 4, paint);
}
自定義進度條時,就可以直接畫線了。
setStrokeJoin
設置多次調用 Path.lineTo 這種線段之間連接處的樣式。
- Paint.Join.MITER: 直角的樣式
- Paint.Join.ROUND:圓弧
- Paint.Join.BEVEL:在直角樣式上切了一個小三角形
示例如下:
public StrokeJoinCapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setStrokeWidth(60);
paint.setStyle(Paint.Style.STROKE);
paint.setDither(true);
paint.setColor(Color.RED);
paint.setStrokeJoin(Paint.Join.MITER);
// paint.setStrokeJoin(Paint.Join.ROUND);
// paint.setStrokeJoin(Paint.Join.BEVEL);
path = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int temp = 120;
path.moveTo(temp, temp);
path.lineTo(getMeasuredWidth() - temp, temp);
path.lineTo(getMeasuredWidth() - temp, getMeasuredHeight() / 2);
path.lineTo(temp, getMeasuredHeight() / 2);
path.lineTo(temp, getMeasuredHeight() - temp);
path.lineTo(getMeasuredWidth() - temp, getMeasuredHeight() - temp);
canvas.drawPath(path, paint);
}
注意拐角處:
Paint.Join.MITER:
Paint.Join.ROUND:
Paint.Join.BEVEL:
setPathEffect
系統給我們提供了六種效果,分別是 CornerPathEffect
、DashPathEffect
、DiscretePathEffect
、PathDashPathEffect
、ComposePathEffect
、SumPathEffect
。下面我們來一一介紹。
CornerPathEffect
CornerPathEffect 的作用就是將原來的直線拐角變成圓形拐角,構造函數傳入的就是拐角的半徑。
/**
* @param radius 拐角處弧度半徑
*/
public CornerPathEffect(float radius) {}
示例:
PathEffect pathEffect;
public StrokeJoinCapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setStrokeWidth(30);
paint.setStyle(Paint.Style.STROKE);
paint.setDither(true);
paint.setColor(Color.RED);
path = new Path();
pathEffect = new CornerPathEffect(50);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int temp = 120;
path.moveTo(temp, temp);
path.lineTo(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
path.lineTo(getMeasuredWidth() - temp, temp);
paint.setPathEffect(pathEffect);
canvas.drawPath(path, paint);
}
效果圖:
DashPathEffect
DashPathEffect 的作用就是實現 虛線效果。
/**
* @param 分割線的長度變化值數組,必須大於等於2
* @param phase 偏移大小
*/
public DashPathEffect(float intervals[], float phase) {}
示例:
int phase = 0;
PathEffect pathEffect;
public StrokeJoinCapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
paint.setDither(true);
paint.setColor(Color.RED);
path = new Path();
float [] f = {20,10};
pathEffect = new DashPathEffect(f,phase);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int temp = 120;
path.moveTo(temp, temp);
path.lineTo(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
path.lineTo(getMeasuredWidth() - temp, temp);
paint.setPathEffect(pathEffect);
canvas.drawPath(path, paint);
}
效果圖:
我們可以通過 修改 偏移值的大小來 實現如下效果:
@Override
protected void onDraw(Canvas canvas) {
...
float[] f = {20, 10};
pathEffect = new DashPathEffect(f, phase);
paint.setPathEffect(pathEffect);
canvas.drawPath(path, paint);
phase += 5;
postInvalidate();
}
DiscretePathEffect
/**
* @param segmentLength 每段線段長度
* @param deviation 偏移
*/
public DiscretePathEffect(float segmentLength, float deviation) { }
DiscretePathEffect 就是將原來路徑分隔很多段 segmentLength
長的線段,然後將每條線段隨機偏移 deviation
的位置,deviation
越大,抖動幅度越大,效果圖如下:
示例:
public StrokeJoinCapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
paint.setDither(true);
paint.setColor(Color.RED);
path = new Path();
pathEffect = new DiscretePathEffect(50, 50);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int temp = 120;
path.moveTo(temp, temp);
path.lineTo(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
path.lineTo(getMeasuredWidth() - temp, temp);
paint.setPathEffect(pathEffect);
canvas.drawPath(path, paint);
}
效果圖:
PathDashPathEffect
/**
* @param shape 印戳的路徑
* @param advance 每個印戳的距離
* @param phase 印戳的偏移大小
* @param style 每個印戳的變化規則
*/
public PathDashPathEffect(Path shape, float advance, float phase, Style style) {}
PathDashPathEffect 就是再原有路徑上用 PathDashPathEffect 構造函數中的 shape 去繪製這條路徑。提供了TRANSLATE、ROTATE、MORPH 這三種樣式,主要區分拐角處。
效果如下:
示例:
public StrokeJoinCapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
paint.setDither(true);
paint.setColor(Color.RED);
path = new Path();
dashPath = new Path();
dashPath.addCircle(0, 0, 10, Path.Direction.CCW);
dashPath.moveTo(20, 0);
dashPath.lineTo(0, 20);
dashPath.lineTo(40, 20);
dashPath.close();
pathEffect = new PathDashPathEffect(dashPath, 60, 0, PathDashPathEffect.Style.TRANSLATE);
// pathEffect = new PathDashPathEffect(dashPath, 60, 0, PathDashPathEffect.Style.ROTATE);
// pathEffect = new PathDashPathEffect(dashPath, 60, 0, PathDashPathEffect.Style.MORPH);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int temp = 120;
path.moveTo(temp, temp);
path.lineTo(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
path.lineTo(getMeasuredWidth() - temp, temp);
canvas.drawPath(path, paint);
canvas.translate(0, 100);
paint.setPathEffect(pathEffect);
canvas.drawPath(path, paint);
}
效果圖,主要看拐角處:
SumPathEffect和 ComposePathEffect
這兩個都是用來合併兩個特效的。
/**
* (e.g. first(path) + second(path))
*/
public SumPathEffect(PathEffect first, PathEffect second) {}
/**
* (e.g. outer(inner(path))).
*/
public ComposePathEffect(PathEffect outerpe, PathEffect innerpe) {}
SumPathEffect 是分別對原始路徑分別作用第一個特效和第二個特效。然後再將這兩條路徑合併,做爲最終結果。可以理解爲兩個特效集合的並集。
ComposePathEffect 合併兩個特效是有先後順序的,它會先將第二個參數的PathEffect innerpe的特效作用於路徑上,然後再在此加了特效的路徑上作用第二個特效。可以理解爲兩個特效集合的交集。
示例:
public StrokeJoinCapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
paint.setDither(true);
paint.setColor(Color.RED);
path = new Path();
pathEffect1 = new DiscretePathEffect(10, 10);
float[] f = {20, 10};
pathEffect2 = new DashPathEffect(f, 10);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int temp = 120;
path.moveTo(temp, temp);
path.lineTo(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
path.lineTo(getMeasuredWidth() - temp, temp);
canvas.drawPath(path, paint);
canvas.translate(0, 100);
paint.setPathEffect(new SumPathEffect(pathEffect1, pathEffect2));
canvas.drawPath(path, paint);
canvas.translate(0, 200);
paint.setPathEffect(new ComposePathEffect(pathEffect1, pathEffect2));
canvas.drawPath(path, paint);
}
效果圖:
參考文章
如果覺得不錯的話,請幫忙點個讚唄。
以上
掃描下面的二維碼,關注我的公衆號 Android1024, 點關注,不迷路。