主要是对Path类的理解, 还有对其quadTo函数的运用
一些细节: 无论是quadTo还是lineTo, 最后Path都会移到终点的了,不必要也不能使用moveTo, 否则fill出来的图像断断续续的
效果图:
原理图(简单来说就是把几个正弦波拼在一起):
PathActivity3.java
public class PathActivity3 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_path_test3); final WaterView waterView= (WaterView) findViewById(R.id.water_view); ((SeekBar) findViewById(R.id.seek_bar)).setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { waterView.setWaterHeight(progress/100f); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); } }
WaterView.java
public class WaterView extends View { Path path; Paint paint=new Paint(); int POINT_NUM=8; int VISIBLE_POINT_NUM=4; int WAVE_WIDTH,WAVE_HEIGHT; int waterHeight; int curX=0; int speed=5; int viewWidth,viewHeight; public WaterView(Context context, AttributeSet attrs) { super(context, attrs); paint.setAntiAlias(true); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(2); paint.setColor(Color.BLUE); //start anim Timer timer=new Timer(); timer.schedule(new TimerTask() { @Override public void run() { curX+=speed; if (curX>WAVE_WIDTH*4) curX=0; postInvalidate(); } },10,20); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); viewWidth=w; viewHeight=h; WAVE_WIDTH=viewWidth/VISIBLE_POINT_NUM; WAVE_HEIGHT=viewHeight/8; waterHeight=viewHeight/2; //set path path=new Path(); path.moveTo(0,0); float x1=0; float y1= 0; float controlRatio=-1; for (int i=0;i<POINT_NUM;i++){ if (i%2==0) controlRatio=-controlRatio; //begin point(x1,y1) //lineTo will move path to the end point //moveTo(x1,y1) will make path ont consecutive so that action fill occur error //path.moveTo(x1,y1); float sinResult= (float) Math.sin(Math.PI/2 * (i+1)); float x2=i*WAVE_WIDTH+WAVE_WIDTH; float y2= (float) sinResult*WAVE_HEIGHT/2; //control point((x1+x2)/2,(y1+y2)/2+controlRatio*WAVE_HEIGHT/4) //end point(x2,y2) path.quadTo((x1+x2)/2,(y1+y2)/2+controlRatio*WAVE_HEIGHT/4,x2,y2); x1=x2; y1=y2; } path.lineTo(x1, viewHeight); path.lineTo(0, viewHeight); path.close(); } @Override protected void onDraw(Canvas canvas) { canvas.translate(-curX, waterHeight); canvas.drawPath(path, paint); } public void setWaterHeight(float v) { waterHeight= (int) (viewHeight*(1-v)); } }