自定义控件学习之canvas和paint相关知识点学习
1,继承自view,实现ondraw方法:
初始化画笔,TextPaint paint,并设置画笔属性:
paint.setFlags(Paint.ANTI_ALIAS_FLAG):画笔抗锯齿。
paint.setStyle(Paint.Style.STROKE):设置画笔样式,默认全部填充Full
{ 1.Paint.Style.STROKE:描边;
2.Paint.Style.FILL_AND_STROKE:描边并填充
3.Paint.Style.FILL:填充
}
paint.setStrokeCap(Paint.Cap.ROUND):画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式
{ 1,圆形样式 Cap.ROUND,
2,方形样式 Cap.SQUARE
}
paint.setColor(0xff00ff00):设置画笔颜色
Canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint):利用TextPaint在canvas上绘制线条:坐标从(startX,startY)到(stopX,stopY),坐标点起点为左上角,起点为0,0
2,在xml布局里面设置自定义布局控件
package com.soyoungboy.customview.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.text.TextPaint; import android.util.AttributeSet; import android.util.Log; import android.view.View; import com.example.customview.R; /** * 自定义view基础 练习 * * @author soyoungboy * */ public class CustomView extends View { public TextPaint paint; private float textHeight; private float fontSize = getResources().getDimensionPixelSize( R.dimen.default_font_size); private float density = getResources().getDisplayMetrics().density; public CustomView(Context context) { super(context); init(null, 0); } public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs, defStyleAttr); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); init(attrs, 0); } /** * 初始化操作 * * @param attrs * @param defStyleAttr */ private void init(AttributeSet attrs, int defStyleAttr) { // 初始化TextPaint paint = new TextPaint(); // paint的默认字体大小 Log.i("iSpring", "默认字体大小: " + paint.getTextSize() + "px"); // paint的默认颜色 Log.i("iSpring", "默认颜色: " + Integer.toString(paint.getColor(), 16)); // paint的默认style是FILL,即填充模式 Log.i("iSpring", "默认style: " + paint.getStyle().toString()); // paint的默认cap是 Log.i("iSpring", "默认cap: " + paint.getStrokeCap().toString()); // paint默认的strokeWidth Log.i("iSpring", "默认strokeWidth: " + paint.getStrokeWidth() + ""); paint.setFlags(Paint.ANTI_ALIAS_FLAG);// 设置为抗锯齿 paint.setTextSize(fontSize);// 设置字体大小 // 初始化textHeight textHeight = fontSize; // Paint.FontMetrics fontMetrics = paint.getFontMetrics(); // textHeight = Math.abs(fontMetrics.top) + fontMetrics.bottom; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawAxis(canvas); } /** * 绘制坐标系 * * @param canvas */ private void drawAxis(Canvas canvas) { int canvasWidth = canvas.getWidth(); int canvasHeight = canvas.getHeight(); // 置画笔样式,如果不设置,默认是全部填充(FILL)。可选项为:FILL,FILL_OR_STROKE,或STROKE // 画笔样式分三种: // 1.Paint.Style.STROKE:描边 // 2.Paint.Style.FILL_AND_STROKE:描边并填充 // 3.Paint.Style.FILL:填充 paint.setStyle(Paint.Style.STROKE); // 该方法用来设置我们画笔的 笔触风格 ,比如:ROUND,表示是圆角的笔触。 // 那么什么叫笔触呢,其实很简单,就像我们现实世界中的笔,如果你用圆珠笔在纸上戳一点, // 那么这个点一定是个圆,即便很小,它代表了笔的笔触形状,如果我们把一支铅笔笔尖削成方形的, // 那么画出来的线条会是一条弯曲的“矩形”,这就是笔触的意思。 // 除了ROUND,Paint.Cap还提供了另外两种类型:SQUARE和BUTT paint.setStrokeCap(Paint.Cap.ROUND); //当画笔样式(style)为STROKE或FILL_OR_STROKE时(空心样式时),设置笔刷的粗细度。 paint.setStrokeWidth(6 * density); //用绿色画x轴,用蓝色画y轴 //第一次绘制坐标轴 //设置画笔颜色为绿色 paint.setColor(0xff00ff00);//绿色 //Canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint) //从开始点为0,0的地方绘制线条到canvasWidth,0坐标,也就是说,沿着x轴绘制线条 canvas.drawLine(0, 0, canvasWidth, 0, paint);//绘制x轴 //设置画笔颜色为蓝色 paint.setColor(0xff0000ff);//蓝色,也就说沿着Y轴绘制线条 //从开始点为0,0的地方绘制线条到0,canvasHeight坐标 canvas.drawLine(0, 0, 0, canvasHeight, paint);//绘制y轴 } }
背景颜色绘制:
canvas.drawARGB(a, r, g, b):其中a,r,g,b为0到255的int值,用来组成画布的背景颜色
canvas.drawColor(Color.BLUE) :将会以颜色ARBG填充整个控件的Canvas背景
canvas.drawColor(Color.BLUE, Mode.SCREEN) :绘制颜色,但是要制定一个mode
mode参数:
对应下图:
对应如下规则:
SRC :只绘制源图像
DST :只绘制目标图像
DST_OVER :在源图像的顶部绘制目标图像
DST_IN :只在源图像和目标图像相交的地方绘制目标图像
DST_OUT :只在源图像和目标图像不相交的地方绘制目标图像
DST_ATOP :在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像
SRC_OVER :在目标图像的顶部绘制源图像
SRC_IN :只在源图像和目标图像相交的地方绘制源图像
SRC_OUT :只在源图像和目标图像不相交的地方绘制源图像
SRC_ATOP :在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像
XOR :在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容
LIGHTEN :获得每个位置上两幅图像中最亮的像素并显示
DARKEN :获得每个位置上两幅图像中最暗的像素并显示
MULTIPLY :将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255
SCREEN :反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255)
如上代码ondraw里面代码:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawARGB(168, 138, 179, 233); }
效果:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); }
效果:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLUE, Mode.SCREEN); }
绘制文字
博客园里面有篇文字讲的很细,可以去看看:http://www.cnblogs.com/tianzhijiexian/p/4297664.html
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置抗锯齿 paint.setAntiAlias(true); //控制文字大小 paint.setTextSize(24); //控制文字颜色 paint.setColor(Color.RED); //设置文字粗体 paint.setFakeBoldText(true); //设置是否显示下划线 paint.setUnderlineText(true); //设置字体类型 paint.setTypeface(Typeface.SANS_SERIF); //左上角倾斜 paint.setTextSkewX(-0.25f); //文本删除线 paint.setStrikeThruText(true); //第一个为显示的内容,第二个参数为文字显示的x轴坐标,第三个为Y坐标 canvas.drawText("我是大帅哥", canvas.getWidth()/2, canvas.getHeight()/2, paint); }
效果如下:
绘制点:
StrokeWidth -- 控制宽度
color -- 控制颜色
StrokeCap -- 控制形状
通过drawpoint来进行绘制
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint.setStrokeWidth(100); paint.setColor(Color.YELLOW); // paint.setStrokeCap(Paint.Cap.SQUARE); paint.setStrokeCap(Paint.Cap.BUTT); canvas.drawPoint(canvas.getWidth()/3, canvas.getHeight()/3, paint); }
效果:
绘制方块
擦,还有这种:
如上三种方法来进行绘制方块:
canvas.drawcircle为绘制圆
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Rect r = new Rect(100, 100, 300, 300); //方块背后的颜色 canvas.drawColor(Color.RED); //绘制方格的颜色 paint.setColor(Color.WHITE); //绘制方格 canvas.drawRect(r, paint); paint.setColor(Color.BLACK); //绘制黑色的圆 canvas.drawCircle(200, 200, 100, paint); }
绘制圆,style有三种:
代码试试,看看效果:
填充,填充轮廓和里面
Fill或者Fill_AND_STROKE:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Rect r = new Rect(100, 100, 300, 300); //方块背后的颜色 canvas.drawColor(Color.RED); //绘制方格的颜色 paint.setColor(Color.WHITE); //绘制方格 canvas.drawRect(r, paint); paint.setColor(Color.BLACK); paint.setStyle(Style.FILL); //绘制黑色的圆 canvas.drawCircle(200, 200, 100, paint); }
效果如上图:
设置为:
Stoke,绘制轮廓
paint.setStyle(Style.STROKE);
绘制椭圆
虽然调用的是drawoval,其实还是主要通过RectF和上下左右的位置的计算来进行控制
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int Width = canvas.getWidth(); int height = canvas.getHeight()/2; float left = 10 * density; float right = Width-left; float top = height/4; float bottom = height/2+height/4; paint.setColor(Color.BLACK); paint.setStyle(Style.FILL); RectF f = new RectF(left, top, right, bottom); //绘制黄色的椭圆 canvas.drawOval(f, paint); }
paint.setStyle(Style.STROKE)为图2
drawBitmap:绘制图片
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher); canvas.drawBitmap(mBmp , mBmp.getWidth(), mBmp.getHeight(), paint); canvas.restore(); }
BitmpaUtils.drawableToBitmap方法代码,将drawable转换为bitmap:
public static Bitmap drawableToBitmap(Context context, int resId) { BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = true; InputStream is = context.getResources().openRawResource(resId); return BitmapFactory.decodeStream(is, null, opt); }
执行效果:
缩放借助Matrix来实现:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher); canvas.drawBitmap(mBmp , mBmp.getWidth(), mBmp.getHeight(), paint); Matrix matrix=new Matrix(); matrix.postScale(0.5f, 0.5f); Bitmap dstbmp=Bitmap.createBitmap(mBmp,0,0,mBmp.getWidth(), mBmp.getHeight(),matrix,true); canvas.drawBitmap(dstbmp, 10, 10, null); }
看下效果,宽高缩小一半:
对图片进行旋转:
matrix.postRotate(45);
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Matrix matrix=new Matrix(); matrix.postRotate(45); Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher); Bitmap dstbmp=Bitmap.createBitmap(mBmp,0,0,mBmp.getWidth(), mBmp.getHeight(),matrix,true); canvas.drawBitmap(dstbmp, 10, 10, null); }