更多贝塞尔曲线细节可参照:http://blog.csdn.net/flash129/article/details/8234599
Path就像它的原本的意思一样是路径的意思,它可以根据设置点来绘制各种图形。
Path的初始化也是用new完成的。一般在第二个构造器中。
Path的对象用path.moveTo(100,100);设置起始位置, 即我们下笔的位置path.lineTo(0,200);设置下一个位置。当需要一个闭合图形时最后调用
path.close();//收尾连接.
在path中还定义了一些特殊的图形,例如圆。与canvas直接调用方法画圆的方法有些不同,这里还指出了方向Path.Direction.CCW表示逆时针,Path.Direction.CW表示顺时针。
BitMap就是将某个图像写到自定义的View中并可以对其进行包括平移,旋转缩放等操作。
BitMap的初始化:
mbitMap= BitmapFactory.decodeResource(getResources(), R.mipmap.aa);//对BitMap初始化。R.mipmap.aa就是我们进行写入的图片。
可以通过调用bitwidth=mbitMap.getWidth();
bitheigt=mbitMap.getHeight();获得图片的宽度和高度。
在 onDraw()中调用 canvas.drawBitmap(bitmap,0,0,mpaint);就可以将图片画到画布上。(0,0)是图片开始的位置。
可以通过Matrix的值的设置对图片进行平移,旋转,缩放等操作。
Matrix的初始化为: private Matrix matrix=new Matrix ();
matrix.reset();为将matrix中的数据清空,恢复为默认值。
它是设置paint的画图模式的。
当我们不是根据现有的图片在画布上进行BiMap绘制的时候,想自己画一些集合图形的时候,就必须在BitMap上再创建一个Canvas,在这个Canvas上进行绘制,最后再调用原有的Canvas进行绘制。
1、建立PorterDuffXfermode的对象,并设置相应的mode。
PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);
2、当建立了mode,就要设置到相应的画笔上:
代码如下:
PorterDuffXfermode mode=new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
mPaintRect.setXfermode(mode);
3、既然是自定义的bitmap就一定要设置其宽度和高度。一般在onMeasure方法中设置,因为我们可能要用到View的宽和高。只有运行到onMeasure才能获得View的宽和高。
mBitmap=Bitmap.createBitmap(mWidth,mHeight,Bitmap.Config.ARGB_8888);
4、新建一个Canvas,并将其设置为BitMap的。在onMeasure中代码如下:
private Canvas canvasBit;
canvasBit=new Canvas(mBitmap);
public class MyPathView extends View {
private Paint mPaint;
private Paint mPaintPoint;
private int mWidth;
private int mHeight;
private Path mPath;
private static final int NEED_INVALIDATE=0X23;
private int count=0;
private int size=0;
private boolean isAdd=true;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case NEED_INVALIDATE:
count+=5;
if (count>160){
count=0;
}
if (isAdd){
size++;
if (size>20){
isAdd=false;
}
}else {
size--;
if (size<-21){
isAdd=true;
}
}
invalidate();
handler.sendEmptyMessageDelayed(NEED_INVALIDATE,50);
break;
}
}
};
public MyPathView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint=new Paint();
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPaint.setTextSize(50);
mPath=new Path();
mPaintPoint=new Paint();
mPaintPoint.setColor(Color.RED);
mPaintPoint.setStrokeWidth(10);
mPaintPoint.setStyle(Paint.Style.STROKE);
handler.sendEmptyMessageDelayed(NEED_INVALIDATE,100);
}
public MyPathView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
mPath.reset();//重置,避免波浪线加宽
mPath.moveTo(count, mHeight / 2);
for (int i=0;i<10;i++){
mPath.rQuadTo(50,size,80,0);
mPath.rQuadTo(50,-size,80,0);
}
canvas.drawPath(mPath, mPaint);
canvas.drawCircle(mWidth/2,mHeight/2,150,mPaintPoint);
}
}
public class MyPathView extends View {
private Paint mPaint;
private Paint mPaintPoint;
private int mWidth;
private int mHeight;
private Path mPath;
public MyPathView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint=new Paint();
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPaint.setTextSize(50);
mPath=new Path();
mPaintPoint=new Paint();
mPaintPoint.setColor(Color.RED);
mPaintPoint.setStrokeWidth(10);
mPaintPoint.setStyle(Paint.Style.STROKE);
handler.sendEmptyMessageDelayed(NEED_INVALIDATE,100);
}
public MyPathView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
mPath.moveTo(100,100);//贝塞尔曲线开始点的坐标
mPath.quadTo(100, 400, 300, 300);//前两个为控制点坐标,后两个是结束点坐标
canvas.drawPath(mPath, mPaint);
canvas.drawPoint(100,100,mPaintPoint);
canvas.drawPoint(100,400,mPaintPoint);
canvas.drawPoint(300,300,mPaintPoint);
>
public class MyPathView extends View {
private Paint mPaint;
private Paint mPaintPoint;
private int mWidth;
private int mHeight;
private Path mPath;
public MyPathView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint=new Paint();
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPaint.setTextSize(50);
mPath=new Path();
mPaintPoint=new Paint();
mPaintPoint.setColor(Color.RED);
mPaintPoint.setStrokeWidth(10);
mPaintPoint.setStyle(Paint.Style.STROKE);
handler.sendEmptyMessageDelayed(NEED_INVALIDATE,100);
}
public MyPathView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPath.moveTo(100, 100);
mPath.lineTo(0, 200);
mPath.lineTo(200, 200);
mPath.addCircle(mWidth/2,mHeight/2,300,Path.Direction.CCW);
mPath.close();//前面设置为空心的时候需要关闭画线。
canvas.drawPath(mPath,mPaint);
canvas.drawTextOnPath("请把这个沿着三角形的边写上去",mPath,0,0,mPaint);
<com.example.administrator.definedviewdemo.Wiget.MyPathView
android:layout_width="match_parent"
android:layout_height="match_parent" />
public class MyBitMap extends View {
private int mWidth;
private int mHeight;
private Paint mPaint;
private Bitmap mBitmap;
private Matrix matrix;
private int mBitmapWidth;
private int mBitmapHeight;
public MyBitMap(Context context) {
super(context);
}
public MyBitMap(Context context, AttributeSet attrs) {
super(context, attrs);
mBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.childen);
mPaint=new Paint();
matrix=new Matrix();
mBitmapWidth=mBitmap.getWidth();
mBitmapHeight=mBitmap.getHeight();
Log.d("bitmap1","高:"+mBitmap.getHeight()+"宽"+mBitmap.getWidth());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
matrix.reset();
canvas.drawBitmap(mBitmap, matrix, mPaint);
matrix.postScale(2, 2);//放大,缩小
canvas.drawBitmap(mBitmap, matrix, mPaint);
matrix.reset();
canvas.drawBitmap(mBitmap, matrix, mPaint);//可以不用
matrix.postTranslate(0, mBitmapHeight * 2);//平移
canvas.drawBitmap(mBitmap, matrix, mPaint);
matrix.reset();
matrix.postRotate(180);//旋转 必须和后面这句postTranslate同时用
matrix.postTranslate(mBitmapWidth, mBitmapHeight);
canvas.drawBitmap(mBitmap, matrix, mPaint);
matrix.reset();
matrix.postSkew(0, 1);//错切
canvas.drawBitmap(mBitmap, matrix, mPaint);
matrix.reset();
float matrix_values[]={1f,0f,0f,0f,-1f,0f,0f,0f,1f};//关于X轴对称
matrix.setValues(matrix_values);
matrix.postTranslate(0, mBitmapHeight * 1);
canvas.drawBitmap(mBitmap, matrix, mPaint);
matrix.reset();
float matrix_values2[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};//沿y轴翻转
matrix.setValues(matrix_values2);
matrix.postTranslate(mBitmapWidth*2, 0);
canvas.drawBitmap(mBitmap, matrix, mPaint);
}
}
<com.example.administrator.definedviewdemo.Wiget.MyBitMap
android:layout_width="match_parent"
android:layout_height="match_parent" />