Canvas() //构造方法
Canvas(Bitmap bitmap) //带参构造方法,创建一个以bitmap位图为背景的Canvas
clipPath(Path path, Region.Op op) //根据特殊path组合裁切图像,Region.Op定义了Region支持的区域间运算种类。
clipRect(Rect rect, Region.Op op) //根据矩形组合裁切图像
clipRegion(Region region, Region.Op op)
concat(Matrix matrix) //通过matrix的设置可以对绘制的图形进行绘制伸缩和位移
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) //绘制弧形
drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) //绘制bitmap位图
drawPicture(Picture picture, RectF dst) //绘制图片
drawCircle(float cx, float cy, float radius, Paint paint) //绘制圆
drawLine(float startX, float startY, float stopX, float stopY, Paint paint) //绘制线
drawLines(float[] pts, int offset, int count, Paint paint) //可以选择性的去掉一些数据绘制多条线
drawOval(RectF oval, Paint paint) //绘制椭圆
drawPath(Path path, Paint paint) //绘制路径
drawPoint(float x, float y, Paint paint) //绘制点
drawPoints(float[] pts, int offset, int count, Paint paint) //绘制多个点
drawPosText(String text, float[] pos, Paint paint) //绘制文本,float[] pos指定每个文本位置
drawRect(float left, float top, float right, float bottom, Paint paint) //绘制矩形
drawRoundRect(RectF rect, float rx, float ry, Paint paint) //绘制圆角矩形
drawText(String text, float x, float y, Paint paint) //绘制string文本
drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint) //路径上绘制文本
drawRGB(int r, int g, int b) //使用RGB指定颜色填充canvas的bitmap画布
drawARGB(int a, int r, int g, int b) //使用ARGB指定颜色填充canvas的bitmap画布
save() //保存Canvas状态,save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作
restore() //恢复Canvas之前保存的状态,防止save后对Canvas执行的操作对后续的绘制有影响
rotate(float degrees, float px, float py) //旋转
scale(float sx, float sy) //缩放
skew(float sx, float sy) //扭曲
translate(float dx, float dy) //平移
isUnderlineText() //判断是否有下划线
setUnderlineText(boolean underlineText) //设置下划线
getLetterSpacing() //获取字符间的间距
setLetterSpacing(float letterSpacing) //设置字符间距
getFontSpacing() //获取行间距
isStrikeThruText() //判断文本是否有删除线
setStrikeThruText(boolean strikeThruText) //设置文本删除线
getTextSize() //获取字体大小
setTextSize(float textSize) //设置字体大小
getTypeface() //获取文字字体类型
setTypeface(Typeface typeface) //设置文字字体类型
getTextSkewX() //获取斜体文字的值
setTextSkewX(float skewX) //设置斜体文字的值,负数为右倾斜,正数为左倾斜 官方推荐-0.25
getTextScaleX() //获取文字水平缩放值
setTextScaleX(float scaleX) //设置文本水平缩放值
getTextAlign() //获取文本对其方式
setTextAlign(Paint.Align align) //设置文本对其方式
ascent() //baseline之上至字符最高处的距离
descent() //baseline下面到字符最低处的距离
measureText(CharSequence text, int start, int end) //测绘文本的宽度
getTextBounds(char[] text, int index, int count, Rect bounds) //获取文本宽高
getTextWidths(String text, int start, int end, float[] widths) //精确获取文本宽度
getTextLocale() //获取文本语言地理位置
setTextLocale(Locale locale) //设置文本地理位置,也就是设置对应的语言
//设置画笔颜色
setARGB(int a, int r, int g, int b)
setAlpha(int a)
setColor(int color)
//获取画笔颜色
getAlpha()
getColor()
isAntiAlias() //判断是否抗锯齿
setAntiAlias(boolean aa) //设置抗锯齿,虽然耗资源耗时间,但是一般会开启
getStyle() //获取画笔样式
setStyle(Paint.Style style) //设置画笔样式,FILL:实心; FILL_OR_STROKE:同时实心和空心; STROKE:空心
setStrokeCap(Cap cap) //设置画笔样式, 圆形(Cap.Round),方形(Cap.SQUARE)
getStrokeWidth() //获取画笔的粗细大小
setStrokeWidth(float width) //设置画笔的粗细大小
clearShadowLayer() //清除阴影层
setShadowLayer(float radius, float dx, float dy, int shadowColor) //设置阴影
getXfermode() //获取图形绘制的像素融合模式
setXfermode(Xfermode xfermode) //设置图形绘制的像素融合模式和叠加模式,就是新绘制的像素与Canvas上对应位置已有的像素按照混合规则进行颜色混合
getShader() //获取图形的渲染方式
setShader(Shader shader) //设置图形的渲染方式,分别有线性渲染(LinearGradient) 环形渲染(RadialGradient) 组合渲染(ComposeShader) 扫描渐变渲染/梯度渲染(SweepGradient)
reset() //清除画笔复位
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-11.
*/
public class DrawCircleView extends View {
Paint paint;
public DrawCircleView(Context context) {
super(context);
}
public DrawCircleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-11.
*/
public class DrawCircleView extends View {
Paint paint;
public DrawCircleView(Context context) {
super(context);
}
public DrawCircleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//初始化画笔
paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置画笔颜色
paint.setColor(getResources().getColor(R.color.colorAccent));
//设置画笔要是,圆形/方形/其他
paint.setStrokeCap(Paint.Cap.BUTT);
//设置实心圆
paint.setStyle(Paint.Style.FILL);
//设置画笔大小
paint.setStrokeWidth(2);
//设置阴影
paint.setShadowLayer(5,5,5, Color.BLUE);
//绘制实心圆
canvas.drawCircle(300,200,100,paint);
//设置为空心
paint.setStyle(Paint.Style.STROKE);
//设置画笔大小
paint.setStrokeWidth(3);
//绘制
canvas.drawCircle(500,200,100,paint);
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-15.
*/
public class DrawRectView extends View {
public DrawRectView(Context context) {
super(context);
}
public DrawRectView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置画笔的样式
paint.setStrokeCap(Paint.Cap.ROUND);
//设置画笔粗细大小
paint.setStrokeWidth(3);
//设置画笔的所画图形的样式
paint.setStyle(Paint.Style.FILL);
//设置画笔的颜色
paint.setColor(Color.GREEN);
//绘制矩形 drawRect(left顶点X坐标, left顶点Y坐标, 右底部X坐标, 右底Y坐标, @NonNull Paint paint)
canvas.drawRect(200,200,400,400,paint);
//从新设置画笔所画图形样式
paint.setStyle(Paint.Style.STROKE);
//重新设置画笔大小
paint.setStrokeWidth(5);
//绘制
RectF rect = new RectF(200,420,400,620);
canvas.drawRect(rect,paint);
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-14.
*/
public class DrawRoundRectView extends View {
public DrawRoundRectView(Context context) {
super(context);
}
public DrawRoundRectView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
//声明并初始化
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置画出的图形是实心还是空心
paint.setStyle(Paint.Style.FILL);
//设置画笔粗细
paint.setStrokeWidth(2);
//设置画笔的样式
paint.setStrokeCap(Paint.Cap.ROUND);
//设置画笔颜色
paint.setColor(getResources().getColor(R.color.colorPrimaryDark));
/* if (Build.VERSION.SDK_INT>=21){
//需要在API 21版本及其以后才能使用,和下面效果相同
canvas.drawRoundRect(100,100,200,200,20,20,paint);
}*/
RectF rect = new RectF(200,200,400,400);
canvas.drawRoundRect(rect,50,50,paint);
//从新设置画笔大小
paint.setStrokeWidth(5);
//设置画笔画出的图形未空心
paint.setStyle(Paint.Style.STROKE);
//绘制矩形
// RectF(left顶点x坐标, left顶点Y坐标, right边底部x坐标, right边底部Y坐标)
RectF rect2 = new RectF(200,420,400,620);
//绘制圆角矩形
//drawRoundRect(@NonNull RectF rect, x方向上的圆角半径, Y方向上的圆角半径, @NonNull Paint paint)
canvas.drawRoundRect(rect2,50,50,paint);
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawOvalView extends View {
public DrawOvalView(Context context) {
super(context);
}
public DrawOvalView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置画笔笔尖样式
paint.setStrokeCap(Paint.Cap.ROUND);
//设置所画图形的填充样式
paint.setStyle(Paint.Style.FILL);
//设置画笔颜色
paint.setColor(getResources().getColor(R.color.colorAccent));
//实例化一个包裹椭圆的矩形,如果为正方形,则椭圆为圆
RectF rectF = new RectF(200,200,500,400);
//设置画布颜色,方便与paint.setColor()对比,看看他们的区别
canvas.drawColor(Color.BLACK);
//绘制椭圆
canvas.drawOval(rectF,paint);
//设置画笔的大小
paint.setStrokeWidth(5);
//设置绘画图形为空心
paint.setStyle(Paint.Style.STROKE);
//绘制
if (Build.VERSION.SDK_INT>=21){
//API 21以上才能用,与上面的绘画方式效果一致
canvas.drawOval(200,450,500,650,paint);
}
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawPointView extends View {
public DrawPointView(Context context) {
super(context);
}
public DrawPointView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true);
//设置画笔大小,我这边设置的大点,方便观察
paint.setStrokeWidth(50);
//设置画笔笔尖样式,默认为Paint.Cap.SQUARE,待会切换一下,你就会知道它的作用了
// 网上有说在设置paint.setStrokeCap(Paint.Cap.ROUND|SQUARE);之前需要同时设置
//paint.setStrokeJoin(Paint.Join.ROUND|MITER);我测试了好像不需要也能达到切换的目的
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setColor(getResources().getColor(R.color.colorAccent));
canvas.drawPoint(200,200,paint);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawPoint(300,200,paint);
paint.setStrokeCap(Paint.Cap.SQUARE);
paint.setColor(getResources().getColor(R.color.colorAccent));
canvas.drawPoint(400,200,paint);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawPoint(500,200,paint);
//设置画笔样式
paint.setStrokeCap(Paint.Cap.ROUND);
//设置画笔颜色
paint.setColor(getResources().getColor(R.color.colorAccent));
//绘制多个点
canvas.drawPoints(new float[]{150,300,250,300,350,300,450,300,550,300},paint);
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawLineView extends View {
public DrawLineView(Context context) {
super(context);
}
public DrawLineView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置画笔样式
paint.setStrokeCap(Paint.Cap.ROUND);
//设置画笔颜色
paint.setColor(Color.RED);
//设置画笔大小
paint.setStrokeWidth(20);
//画线段,参数分别是线段起始点的坐标和终点的坐标,和预设的画笔
canvas.drawLine(100,200,600,200,paint);
//LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
//TileMode tile),(x0,y0) (x1,y1)源码上说是梯度的坐标,不是很懂,我个人理解为后面设置的每一种颜色渲染的长度,坐标间隔越小,渲染的颜色长度越短
//int colors[]:指示需要渲染的颜色数组 float positions[]:可为null,为null时颜色均匀分布
//TileMode tile:指示平铺模式,分别有REPEAT(重复) CLAMP(像素扩散) MIRROR(镜面投影)
Shader mShader=new LinearGradient(0,0,100,100,
new int[]{Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},
null,Shader.TileMode.REPEAT);
//设置画笔渲染渐变
paint.setShader(mShader);
//绘制渐变线段
canvas.drawLine(100,300,600,300,paint);
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawPathView extends View {
public DrawPathView(Context context) {
super(context);
}
public DrawPathView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置画笔笔尖样式
paint.setStrokeCap(Paint.Cap.ROUND);
//设置填充模式,默认为FILL
paint.setStyle(Paint.Style.FILL);
//设置画笔大小
paint.setStrokeWidth(3);
//设置颜色
paint.setColor(getResources().getColor(R.color.colorPrimary));
/*Path类的几个...To()方法:
* path.moveTo(x,y)移动到某个点
* path.lineTo(x,y)从起始点,默认(0,0)点绘制直线到(x,y)点
* path.arcTo()用来绘制弧形
* path.cubicTo()用来绘制贝塞尔曲线
* path.quadTo()也是绘制贝塞尔曲线的
* */
//实例化路径类
Path path = new Path();
//设置移动,不绘制
path.moveTo(200, 200);
//从(200,200)画到(200,400)
path.lineTo(200, 400);
//从(200,400)画到(400,400)
path.lineTo(400, 400);
//封闭曲线
path.close();
//绘制路径
canvas.drawPath(path, paint);
//设置颜色
paint.setColor(getResources().getColor(R.color.colorAccent));
//设置移动,不绘制
Path path1 = new Path();
path1.moveTo(200, 200);
//从(200,200)画到(200,400)
path1.lineTo(400, 200);
//从(200,400)画到(400,400)
path1.lineTo(400, 400);
//封闭曲线
path1.close();
//绘制
canvas.drawPath(path1, paint);
//初始化路径
Path path2 = new Path();
//设置矩形
RectF rectF = new RectF(420, 200, 620, 500);
//取矩形包裹椭圆0°到270°的弧
path2.arcTo(rectF, 0, 270);
//封闭弧形
path2.close();
//设置填充实心
paint.setStyle(Paint.Style.FILL);
//设置画笔颜色
paint.setColor(getResources().getColor(R.color.colorAccent));
//绘制图形
canvas.drawPath(path2, paint);
/*
*quadTo()绘制贝塞尔曲线
*/
Path path3 = new Path();
//移动到(200,620)点
path3.moveTo(200, 620);
//绘制贝塞尔曲线
path3.quadTo(300, 420, 400, 620);
//设置空心
paint.setStyle(Paint.Style.STROKE);
//绘制曲线
canvas.drawPath(path3, paint);
/*
* cubicTo()绘制贝塞尔曲线
* */
Path path4 = new Path();
//移动到(300,100)点
path4.moveTo(300, 100);
//绘制曲线
path4.cubicTo(300, 100, 5, 300, 300, 500);
//设置不填充
paint.setStyle(Paint.Style.STROKE);
//绘制
canvas.drawPath(path4, paint);
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawTextView extends View {
public DrawTextView(Context context) {
super(context);
}
public DrawTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置画笔颜色
paint.setColor(getResources().getColor(R.color.colorPrimary));
//设置画笔大小
paint.setStrokeWidth(3);
//设置字体大小
paint.setTextSize(30);
//设置文字样式
paint.setTypeface(Typeface.DEFAULT_BOLD);
String str = "我知道,你要说我很帅,哈啊哈哈哈哈,字不够长!";
//全部显示,起点在(200,100)点
canvas.drawText(str,50,100,paint);
//截取4~9的字符串显示
canvas.drawText(str,4,10,200,200,paint);
//实例化路径
Path path = new Path();
//设置圆形状路径,Direction指示文字显示是逆时针向外还是顺时针向内 Path.Direction.CW|Path.Direction.CCW
path.addCircle(400,400,110, Path.Direction.CW);
//更具路径绘制文本
canvas.drawTextOnPath(str,path,0,0,paint);
Path path1 = new Path();
if (Build.VERSION.SDK_INT>=21){
//API 21以上
path1.addOval(300,600,500,900, Path.Direction.CCW);
}
canvas.drawTextOnPath(str,path1,0,0,paint);
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawPosTextView extends View {
public DrawPosTextView(Context context) {
super(context);
}
public DrawPosTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置画笔颜色
paint.setColor(getResources().getColor(R.color.colorAccent));
//设置画笔到校
paint.setStrokeWidth(5);
//设置字体颜色
paint.setTextSize(30);
canvas.drawColor(Color.BLACK);
canvas.drawPosText("你看我帅嘛?",new float[]{100,200,200,100,300,200,300,400,200,500,100,400},paint);
}
}
3.setXfermode(Xfermode xfermode)的运用
setXfermode()方法主要是设置图形绘制的像素融合模式和叠加模式,就是新绘制的像素与Canvas上对应位置已有的像素按照混合规则进行颜色混合package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-17.
*/
public class XfermodeView extends View {
public XfermodeView(Context context) {
super(context);
}
public XfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* 默认的Xfermode
* */
Paint paint = getPaint();
//设置绘制圆的画笔颜色
paint.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 200, 100, paint);
//设置绘制圆角矩形的画笔颜色
paint.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上,当然最好是些兼容性好的,我这里只是为了方便
canvas.drawRoundRect(200, 200, 300, 350, 10, 10, paint);
/*
* PorterDuff.Mode.ADD模式
* */
Paint paint1 = getPaint();
paint1.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 200, 100, paint1);
//设置像素融合模式
paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
paint1.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 200, 600, 350, 10, 10, paint1);
//取消像素融合模式的设置
paint1.setXfermode(null);
/*
* PorterDuff.Mode.CLEAR模式
* */
Paint paint2 = getPaint();
paint2.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 500, 100, paint2);
paint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint2.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(200, 500, 300, 650, 10, 10, paint2);
paint2.setXfermode(null);
/*
* PorterDuff.Mode.DARKEN模式
* */
Paint paint3 = getPaint();
paint3.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 500, 100, paint3);
paint3.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
paint3.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 500, 600, 650, 10, 10, paint3);
paint3.setXfermode(null);
/*
* PorterDuff.Mode.LIGHTEN模式
* */
Paint paint4 = getPaint();
paint4.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 800, 100, paint4);
paint4.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));
paint4.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(200, 800, 300, 950, 10, 10, paint4);
/*
* PorterDuff.Mode.MULTIPLY模式
* */
Paint paint5 = getPaint();
paint5.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 800, 100, paint5);
paint5.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
paint5.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 800, 600, 950, 10, 10, paint5);
paint5.setXfermode(null);
}
public Paint getPaint() {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(5);
return paint;
}
}
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-17.
*/
public class XfermodeView extends View {
public XfermodeView(Context context) {
super(context);
}
public XfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* 默认的Xfermode
* */
Paint paint = getPaint();
//设置绘制圆的画笔颜色
paint.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 200, 100, paint);
//设置绘制圆角矩形的画笔颜色
paint.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上,当然最好是些兼容性好的,我这里只是为了方便
canvas.drawRoundRect(200, 200, 300, 350, 10, 10, paint);
/*
* PorterDuff.Mode.ADD模式
* */
//canvas.saveLayer()在canvas原画布上见一个透明的layer
int layerId = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint1 = getPaint();
paint1.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 200, 100, paint1);
//设置像素融合模式
paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
paint1.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 200, 600, 350, 10, 10, paint1);
//取消像素融合模式的设置
paint1.setXfermode(null);
//将新图层画到canvas上
canvas.restoreToCount(layerId);
/*
* PorterDuff.Mode.CLEAR模式
* */
int layerId2 = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint2 = getPaint();
paint2.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 500, 100, paint2);
paint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint2.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(200, 500, 300, 650, 10, 10, paint2);
paint2.setXfermode(null);
canvas.restoreToCount(layerId2);
/*
* PorterDuff.Mode.DARKEN模式
* */
int layerId3 = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint3 = getPaint();
paint3.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 500, 100, paint3);
//禁用掉CPU硬件加速,采用软件渲染模式,因为DARKEN、LIGHTEN、OVERLAY等几种混合规则在GPU硬件加速效果展示不出来
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
paint3.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
paint3.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 500, 600, 650, 10, 10, paint3);
paint3.setXfermode(null);
canvas.restoreToCount(layerId3);
/*
* PorterDuff.Mode.LIGHTEN模式
* */
int layerId4 = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint4 = getPaint();
paint4.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 800, 100, paint4);
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
paint4.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));
paint4.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(200, 800, 300, 950, 10, 10, paint4);
paint4.setXfermode(null);
canvas.restoreToCount(layerId4);
/*
* PorterDuff.Mode.MULTIPLY模式
* */
int layerId5 = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint5 = getPaint();
paint5.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 800, 100, paint5);
paint5.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
paint5.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 800, 600, 950, 10, 10, paint5);
paint5.setXfermode(null);
canvas.restoreToCount(layerId5);
}
public Paint getPaint() {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(5);
return paint;
}
}
/** [0, 0] */
CLEAR (0),
/** [Sa, Sc] */
SRC (1),
/** [Da, Dc] */
DST (2),
/** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
SRC_OVER (3),
/** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
DST_OVER (4),
/** [Sa * Da, Sc * Da] */
SRC_IN (5),
/** [Sa * Da, Sa * Dc] */
DST_IN (6),
/** [Sa * (1 - Da), Sc * (1 - Da)] */
SRC_OUT (7),
/** [Da * (1 - Sa), Dc * (1 - Sa)] */
DST_OUT (8),
/** [Da, Sc * Da + (1 - Sa) * Dc] */
SRC_ATOP (9),
/** [Sa, Sa * Dc + Sc * (1 - Da)] */
DST_ATOP (10),
/** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */
XOR (11),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
DARKEN (12),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
LIGHTEN (13),
/** [Sa * Da, Sc * Dc] */
MULTIPLY (14),
/** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
SCREEN (15),
/** Saturate(S + D) */
ADD (16),
OVERLAY (17);