前言
研究一個(gè)類使用方法的最好途徑是閱讀官方文檔 DashPathEffect
作用
DashPathEffect作用是將Path的線段虛線化然眼。
構(gòu)造函數(shù)
DashPathEffect 的構(gòu)造函數(shù)有兩個(gè)參數(shù):
DashPathEffect (float[] intervals, float phase)
官方文檔解釋如下:
The intervals array must contain an even number of entries (>=2), with the even indices specifying the "on" intervals, and the odd indices specifying the "off" intervals. phase is an offset into the intervals array (mod the sum of all of the intervals). The intervals array controls the length of the dashes. The paint's strokeWidth controls the thickness of the dashes. Note: this path effect only affects drawing with the paint's style is set to STROKE or FILL_AND_STROKE. It is ignored if the drawing is done with style == FILL.
翻譯成中文如下:
間隔數(shù)組必須包含偶數(shù)個(gè)條目(大于等于2)勒魔,偶數(shù)索引指定“開”間隔愈捅,而奇數(shù)索引指定“關(guān)”間隔哎媚。相位是間隔數(shù)組的偏移量(所有間隔的總和)忽你。間隔數(shù)組控制了沖線的長(zhǎng)度宗侦。畫筆寬度寬度控制著沖線的厚度。注意:路徑效果只對(duì)畫筆樣式為描邊或填充和描邊有效嗅剖。如果畫筆樣式為填充則會(huì)忽略它辩越。
下面通過一個(gè)示例來研究這兩個(gè)參數(shù)的作用。
代碼部分
- MainActivity.java
package ivan.rich.patheffect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ivan.rich.patheffect.MainActivity">
<ivan.rich.patheffect.PathEffectView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
- PathEffectView.java
package ivan.rich.patheffect;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
public class PathEffectView extends View {
private int mWidth;
private int mHeight;
private Paint mLinePaint;
private Paint mPaint;
private Path mPath;
public PathEffectView(Context context) {
this(context, null);
}
public PathEffectView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(20);
mPaint.setColor(getResources().getColor(R.color.colorPrimary));
mPaint.setStyle(Paint.Style.STROKE);
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLinePaint.setStrokeWidth(1);
mLinePaint.setStyle(Paint.Style.STROKE);
mLinePaint.setColor(getResources().getColor(R.color.colorAccent));
mPath = new Path();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 繪制一條參考線
canvas.drawLine(60, 0, 60, mHeight, mLinePaint);
// 繪制第一條虛線
DashPathEffect dashPathEffect1 = new DashPathEffect(new float[]{60, 60}, 0);
mPaint.setPathEffect(dashPathEffect1);
mPath.reset();
mPath.moveTo(0, mHeight / 10);
mPath.lineTo(mWidth, mHeight / 10);
canvas.drawPath(mPath, mPaint);
// 繪制第二條虛線
DashPathEffect dashPathEffect2 = new DashPathEffect(new float[]{60, 60}, 20);
mPaint.setPathEffect(dashPathEffect2);
mPath.reset();
mPath.moveTo(0, mHeight * 2 / 10);
mPath.lineTo(mWidth, mHeight * 2 / 10);
canvas.drawPath(mPath, mPaint);
// 繪制第三條虛線
DashPathEffect dashPathEffect3 = new DashPathEffect(new float[]{60, 60}, 40);
mPaint.setPathEffect(dashPathEffect3);
mPath.reset();
mPath.moveTo(0, mHeight * 3 / 10);
mPath.lineTo(mWidth, mHeight * 3 / 10);
canvas.drawPath(mPath, mPaint);
// 繪制第四條虛線
DashPathEffect dashPathEffect4 = new DashPathEffect(new float[]{60, 60}, 60);
mPaint.setPathEffect(dashPathEffect4);
mPath.reset();
mPath.moveTo(0, mHeight * 4 / 10);
mPath.lineTo(mWidth, mHeight * 4 / 10);
canvas.drawPath(mPath, mPaint);
// 繪制第五條虛線
DashPathEffect dashPathEffect5 = new DashPathEffect(new float[]{60, 60, 30, 30}, 0);
mPaint.setPathEffect(dashPathEffect5);
mPath.reset();
mPath.moveTo(0, mHeight * 6 / 10);
mPath.lineTo(mWidth, mHeight * 6 / 10);
canvas.drawPath(mPath, mPaint);
// 繪制第六條虛線
DashPathEffect dashPathEffect6 = new DashPathEffect(new float[]{60, 30, 30, 60}, 0);
mPaint.setPathEffect(dashPathEffect6);
mPath.reset();
mPath.moveTo(0, mHeight * 7 / 10);
mPath.lineTo(mWidth, mHeight * 7 / 10);
canvas.drawPath(mPath, mPaint);
// 繪制第七條虛線
DashPathEffect dashPathEffect7 = new DashPathEffect(new float[]{30, 60, 60, 30}, 0);
mPaint.setPathEffect(dashPathEffect7);
mPath.reset();
mPath.moveTo(0, mHeight * 8 / 10);
mPath.lineTo(mWidth, mHeight * 8 / 10);
canvas.drawPath(mPath, mPaint);
// 繪制第八條虛線
DashPathEffect dashPathEffect8 = new DashPathEffect(new float[]{30, 30, 60, 60}, 0);
mPaint.setPathEffect(dashPathEffect8);
mPath.reset();
mPath.moveTo(0, mHeight * 9 / 10);
mPath.lineTo(mWidth, mHeight * 9 / 10);
canvas.drawPath(mPath, mPaint);
}
}
運(yùn)行結(jié)果
參數(shù)分析
1.首先看截圖上半部分的四條虛線段信粮,四條虛線對(duì)應(yīng)的DashPathEffect如下:
DashPathEffect dashPathEffect1 = new DashPathEffect(new float[]{60, 60}, 0);
DashPathEffect dashPathEffect2 = new DashPathEffect(new float[]{60, 60}, 20);
DashPathEffect dashPathEffect3 = new DashPathEffect(new float[]{60, 60}, 40);
DashPathEffect dashPathEffect4 = new DashPathEffect(new float[]{60, 60}, 60);
這四個(gè)DashPathEffect的區(qū)別在于第二個(gè)參數(shù)phase值不同黔攒,以參考線為基準(zhǔn)可以清晰地看到phase參數(shù)的作用是將整個(gè)View向“左”移動(dòng)phase。那么將View向左移動(dòng)phase是什么意思呢强缘?下面通過一個(gè)小示例就知道了督惰。
修改PathEffectView的onDraw代碼:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 繪制兩個(gè)條參考線
canvas.drawLine(60, 0, 60, mHeight, mLinePaint);
canvas.drawLine(0, mHeight / 4, mWidth, mHeight / 4, mLinePaint);
DashPathEffect dashPathEffect = new DashPathEffect(new float[]{60, 60}, 60);
mPaint.setPathEffect(dashPathEffect);
mPath.reset();
mPath.moveTo(60, mHeight / 4);
mPath.lineTo(mWidth, mHeight * 3 / 4);
canvas.drawPath(mPath, mPaint);
}
運(yùn)行之后結(jié)果如下:
在圖中繪制了兩條參考線,參考線的交點(diǎn)為Path的起始點(diǎn)旅掂,從(60, mheight/4)到(mWidth, mHeight * 3 / 4)繪制一條直線赏胚,然后給畫筆設(shè)置DashPathEffect,DashPathEffect的第二個(gè)參數(shù)的值設(shè)為60商虐,上面截圖可以清楚看到“左”移60之后的效果觉阅,因?yàn)樘摼€的實(shí)線部分寬度剛好也為60崖疤,所以最后效果就是第一個(gè)實(shí)線段消失了。
2.然后看截圖下半部分的四條虛線段留拾,這四條虛線段對(duì)應(yīng)的DashPathEffect如下:
DashPathEffect dashPathEffect5 = new DashPathEffect(new float[]{60, 60, 30, 30}, 0);
DashPathEffect dashPathEffect6 = new DashPathEffect(new float[]{60, 30, 30, 60}, 0);
DashPathEffect dashPathEffect7 = new DashPathEffect(new float[]{30, 60, 60, 30}, 0);
DashPathEffect dashPathEffect8 = new DashPathEffect(new float[]{60, 60, 40, 40, 20, 20}, 0);
從效果圖可以看出間隔數(shù)組的偶數(shù)索引處數(shù)組值對(duì)應(yīng)的是實(shí)線寬度戳晌,奇數(shù)索引處數(shù)組值對(duì)應(yīng)的是實(shí)線之后空白線的寬度。前面已經(jīng)提到過數(shù)組必須包含偶數(shù)個(gè)條目痴柔,所以“on”和“off”值是對(duì)應(yīng)的沦偎。在繪制View時(shí)系統(tǒng)遍歷當(dāng)前間隔數(shù)組,依次繪制第一個(gè)“on”和第一個(gè)“off”值咳蔚,第二個(gè)“on”和第二個(gè)“off"值豪嚎。。谈火。侈询,照此類推直至繪制完所有對(duì)應(yīng)的"on"和"off”值,然后按照此方法循環(huán)遍歷間隔數(shù)組直至View的繪制完成糯耍。用代碼概括來說就是:
for (i=0 ; i<intervals.length; i+=2) {
// 實(shí)線寬度on
mLineWidth = intervals[i];
// 實(shí)線之間空白線寬度off
mBlankSpace = intervals[i+1];
}
總結(jié)
構(gòu)造函數(shù)
DashPathEffect(float intervals[], float phase)
參數(shù)含義
- intervals: 控制實(shí)線和實(shí)線之后空白線的寬度(數(shù)組長(zhǎng)度必須為偶數(shù))
- phase: 將View向”左“偏移phase
用法
Paint.setPathEffect(DashPathEffect dashPathEffect);