http://my.eoe.cn/37547/archive/3712.html
android 针对path对象提供了一系列的PathEffect类来实现path绘制的特效。想实现path的特殊绘制效果,需要创建一个响应的PathEffect类,然后调用Paint的setPathEffect方法,将PathEffect类的对象作为参数传入,这样在绘制path时就可以根据PathEffect产生响应的效果了。下面详细介绍下相关的PathEffect类。 1. CornerPathEffect(float radius)
圆角效果。将path中的两条线段形成的锐角夹角用圆弧替代。 CornerPathEffect的构造函数的参数指定了圆弧的半径。 注释:只对锐角有效,这是Android官方文档描述的,原文如下:Transforms geometries that are drawn (either STROKE or FILL styles) by replacing any sharp angles between line segments into rounded angles of the specified radius.但是从我的实验结果看,好像钝角也会被处理。
2. DashPathEffect(float[] intervals, float phase) 虚线效果。
用虚线绘制路径。构造函数中的参数含义分别为:intervals: 定义path中的虚线单元。s数组的长度必须大于等于2,而且必须为偶数。phase 表示绘制path是的偏移量。 例如,针对本文提供的例子: e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase); (10,5,5,5)描述了一条由两条线段和两端空白组成的虚线。整条path就由这个虚线组成。 10 表示第一段线段长度为10,5表示第一段线段之后的空白长度为5,第三个5表示第二条线段长度为5,第四个5表示第二段线段之后的空白长度为5. phase表示绘制是的偏移量,如果phase值为5,则表示绘制时会从第一条长度为10的线段的长度为5的地方开始绘制。因此不断改变phase的值就能实现曲线的动画效果。
3. public DiscretePathEffect (float segmentLength, float deviation)。
将原路径切成segmentLength长度定义的线段,并且每条线段在原路径上以deviation指定的偏移量(角度?弧度?)进行偏移。
4. public PathDashPathEffect (Path shape, float advance, float phase, PathDashPathEffect.Style style)。 定义一个新的形状(路径)并将其用作原始路径的轮廓标记。参数说明如下: shape: 定义一个新的形状,绘制出来的路径由一个个这样的形状组成。 advance: 定义两个形状之间的距离。 phase: 定义偏移量,同DashPathEffect种的phase参数含义。 style:定义了图像单元的方向,效果见下图: 第一条蓝色的曲线style取值为:PathDashPathEffect.Style.TRANSLATE 第二条蓝色的曲线style取值为:PathDashPathEffect.Style. MORPH 第三条蓝色的曲线style取值为:PathDashPathEffect.Style. ROTATE 5. public ComposePathEffect (PathEffect outerpe, PathEffect innerpe)。 定义了两种效果的复合作用。 6. public SumPathEffect (PathEffect first, PathEffect second)。
也定义了两种效果的组合作用。但是和ComposePathEffect有区别。ComposePathEffect 效果是两种效果的组合,如一个圆角和一个虚线,显示的结果是一条圆角虚线的路径。SumPathEffect的效果则是两种效果的简单叠加。就是用第一种效果先画一遍,再用第二种效果画一遍。下面的效果图是一个很好的说明。 上图: 3-3 路径特效类效果图 上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package com . example . androidgraphicsprogramm ;
import android.app.Activity ;
import android.content.Context ;
import android.graphics.* ;
import android.os.Bundle ;
import android.view.KeyEvent ;
import android.view.View ;
public class PathEffects extends Activity {
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView ( new SampleView ( this ));
}
private static class SampleView extends View {
private Paint mPaint ;
private Path mPath ;
private PathEffect [] mEffects ;
private int [] mColors ;
private float mPhase = 0 ;
// private static PathEffect makeDash(float phase) {
// return new DashPathEffect(new float[] { 15, 5, 8, 5 }, phase);
// }
private static void makeEffects ( PathEffect [] e , float phase ) {
e [ 0 ] = null ; // no effect
e [ 1 ] = new CornerPathEffect ( 10 );
e [ 2 ] = new DashPathEffect ( new float [] { 10 , 5 , 5 , 5 }, phase );
// e[2] = new PathDashPathEffect(makePathDash(), 12, phase,
// PathDashPathEffect.Style.TRANSLATE);
e [ 3 ] = new PathDashPathEffect ( makePathDash (), 12 , phase ,
PathDashPathEffect . Style . MORPH );
// e[4] = new PathDashPathEffect(makePathDash(), 12, phase,
// PathDashPathEffect.Style.ROTATE);
e [ 4 ] = new ComposePathEffect ( e [ 2 ], e [ 1 ]);
e [ 5 ] = new SumPathEffect ( e [ 2 ], e [ 1 ]);
e [ 6 ] = new DiscretePathEffect ( 25 , 4 );
}
public SampleView ( Context context ) {
super ( context );
setFocusable ( true );
setFocusableInTouchMode ( true );
mPaint = new Paint ( Paint . ANTI_ALIAS_FLAG );
mPaint . setStyle ( Paint . Style . STROKE );
mPaint . setStrokeWidth ( 6 );
mPath = makeFollowPath ();
mEffects = new PathEffect [ 7 ];
mColors = new int [] { Color . BLACK , Color . RED , Color . BLUE ,
Color . GREEN , Color . MAGENTA , Color . BLACK , Color . RED
};
}
@Override protected void onDraw ( Canvas canvas ) {
canvas . drawColor ( Color . WHITE );
RectF bounds = new RectF ();
mPath . computeBounds ( bounds , false );
canvas . translate ( 10 - bounds . left , 10 - bounds . top );
makeEffects ( mEffects , mPhase );
//mPhase ++;
invalidate ();
for ( int i = 0 ; i < mEffects . length ; i ++) {
mPaint . setPathEffect ( mEffects [ i ]);
mPaint . setColor ( mColors [ i ]);
canvas . drawPath ( mPath , mPaint );
canvas . translate ( 0 , 100 );
}
}
@Override public boolean onKeyDown ( int keyCode , KeyEvent event ) {
switch ( keyCode ) {
case KeyEvent . KEYCODE_DPAD_CENTER :
mPath = makeFollowPath ();
return true ;
}
return super . onKeyDown ( keyCode , event );
}
private static Path makeFollowPath () {
Path p = new Path ();
p . moveTo ( 0 , 0 );
for ( int i = 1 ; i <= 20 ; i ++) {
p . lineTo ( i * 20 , ( float ) Math . random () * 100 );
}
return p ;
}
private static Path makePathDash () {
Path p = new Path ();
p . moveTo ( 4 , 0 );
p . lineTo ( 0 , - 4 );
p . lineTo ( 8 , - 4 );
p . lineTo ( 12 , 0 );
p . lineTo ( 8 , 4 );
p . lineTo ( 0 , 4 );
return p ;
}
}
}