1. Path--->quadTo(float x1, float y1, float x2, float y2):
該方法的實現是當我們不僅僅是畫壹條線甚至是畫弧線時會形成平滑的曲線,該曲線又稱為"貝塞爾曲線"(Bezier curve),其中,x1,y1為控制點的坐標值,x2,y2為終點的坐標值;
貝塞爾曲線的形成,就比如我們把壹條橡皮筋拉直,橡皮筋的頭尾部對應起點和終點,然後從拉直的橡皮筋中選擇任意壹點(除頭尾對應的點外)扯動橡皮筋形成的彎曲形狀,而那個扯動橡皮筋的點就是控制點;
下就面以壹個Demo來結合理解quadTo函數的應用,代碼如下:
1).自定義View:
[java] view plaincopy
package com.feixun.hu.pt;
import android.content.Context;
import android.gesture.GestureStroke;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class DrawingWithBezier extends View
{
private float mX;
private float mY;
private final Paint mGesturePaint = new Paint();
private final Path mPath = new Path();
public DrawingWithBezier(Context context)
{
super(context);
mGesturePaint.setAntiAlias(true);
mGesturePaint.setStyle(Style.STROKE);
mGesturePaint.setStrokeWidth(5);
mGesturePaint.setColor(Color.WHITE);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
// TODO Auto-generated method stub
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
touchDown(event);
break;
case MotionEvent.ACTION_MOVE:
touchMove(event);
}
//更新繪制
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas)
{
// TODO Auto-generated method stub
super.onDraw(canvas);
//通過畫布繪制多點形成的圖形
canvas.drawPath(mPath, mGesturePaint);
}
//手指點下屏幕時調用
private void touchDown(MotionEvent event)
{
//mPath.rewind();
//重置繪制路線,即隱藏之前繪制的軌跡
mPath.reset();
float x = event.getX();
float y = event.getY();
mX = x;
mY = y;
//mPath繪制的繪制起點
mPath.moveTo(x, y);
}
//手指在屏幕上滑動時調用
private void touchMove(MotionEvent event)
{
final float x = event.getX();
final float y = event.getY();
final float previousX = mX;
final float previousY = mY;
final float dx = Math.abs(x - previousX);
final float dy = Math.abs(y - previousY);
//兩點之間的距離大於等於3時,生成貝塞爾繪制曲線
if (dx >= 3 || dy >= 3)
{
//設置貝塞爾曲線的操作點為起點和終點的壹半
float cX = (x + previousX) / 2;
float cY = (y + previousY) / 2;
//二次貝塞爾,實現平滑曲線;previousX, previousY為操作點,cX, cY為終點
mPath.quadTo(previousX, previousY, cX, cY);
//第二次執行時,第壹次結束調用的坐標值將作為第二次調用的初始坐標值
mX = x;
mY = y;
}
}
}
2).MainActivity:
[java] view plaincopy
package com.feixun.hu.pt;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(new MySurfaceView(this));
setContentView(new DrawingWithBezier(this));
//setContentView(new DrawingWithoutBezier(this));
}
}
該Demo實現用戶在手機屏幕上滑動手指時,可根據手指滑動的位置繪制出相應的線條,類似輸入法手勢的繪制,所以代碼中的畫筆Paint命名為mGesturePaint;
比如,我們在屏幕上繪制S這個圖案,則形成的圖案如下:
2. Path--->lineTo(float x, float y) :
該方法實現的僅僅是兩點連成壹線的繪制線路,這樣,當我們用這個方法繪制曲線時,缺陷就出來了;下面的例子,同樣還是和上面的Demo差不多,只不過Path調用的是lineTo方法,如下:
1). 自定義View:
[java] view plaincopy
package com.feixun.hu.pt;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class DrawingWithoutBezier extends View
{
private float mX;
private float mY;
private final Paint mGesturePaint = new Paint();
private final Path mPath = new Path();
public DrawingWithoutBezier(Context context)
{
super(context);
mGesturePaint.setAntiAlias(true);
mGesturePaint.setStyle(Style.STROKE);
mGesturePaint.setStrokeWidth(5);
mGesturePaint.setColor(Color.WHITE);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
// TODO Auto-generated method stub
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
touchDown(event);
break;
case MotionEvent.ACTION_MOVE:
touchMove(event);
}
//更新繪制
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas)
{
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawPath(mPath, mGesturePaint);
}
//手指點下屏幕時調用
private void touchDown(MotionEvent event)
{
//mPath.rewind();
mPath.reset();
float x = event.getX();
float y = event.getY();
mX = x;
mY = y;
//mPath繪制的繪制起點
mPath.moveTo(x, y);
}
//手指在屏幕上滑動時調用
private void touchMove(MotionEvent event)
{
final float x = event.getX();
final float y = event.getY();
final float previousX = mX;
final float previousY = mY;
final float dx = Math.abs(x - previousX);
final float dy = Math.abs(y - previousY);
//兩點之間的距離大於等於3時,連接連接兩點形成直線
if (dx >= 3 || dy >= 3)
{
//兩點連成直線
mPath.lineTo(x, y);
//第二次執行時,第壹次結束調用的坐標值將作為第二次調用的初始坐標值
mX = x;
mY = y;
}
}
}
2).MainActivity:
[java] view plaincopy
package com.feixun.hu.pt;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(new MySurfaceView(this));
//setContentView(new DrawingWithBezier(this));
setContentView(new DrawingWithoutBezier(this));
}
}