Android开发

Android 自定义View-Paint

本文主要是介绍Android 自定义View-Paint,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • Paint的使用
    • setStyle
    • setStrokeCap
    • setShadowLayer
    • setColor setARGB
    • setShader
        • PorterBuff.Mode
        • LinearGradient 线性渐变
        • RadialGradient 辐射渐变
        • SweepGradient 扫描渐变
        • BitmapShader 位图填充
        • ComposeShader 混合着色器
    • setColorFilter
        • LightingColorFilter 光照效果
        • 关于ColorFilter的其他博客
    • setXfermode

Paint的使用

setStyle

  • Paint.Style.FILL:填充模式
  • Paint.Style.STROKE:画线模式
  • Paint.Style.FILL_AND_STROKE:填充+画线

在这里插入图片描述

paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(200,100,100,paint);

paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(200,350,100,paint);

paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(200,600,100,paint);

setStrokeCap

设置线头形状:

  • BUFF:平头
  • ROUND:圆头
  • SQUARE:方头

在这里插入图片描述

paint.setStrokeWidth(20);

paint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawLine(50, 50, 300, 50, paint);

paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(50, 100, 300, 100, paint);

paint.setStrokeCap(Paint.Cap.SQUARE);
canvas.drawLine(50, 150, 300, 150, paint);

setShadowLayer

在绘制内容下面加一层阴影

在这里插入图片描述

paint.setTextSize(36);
paint.setShadowLayer(10, 0, 0, Color.RED);
canvas.drawText("hello world", 100, 100, paint);

setColor setARGB

在这里插入图片描述

paint.setColor(Color.parseColor("#ff0000"));
canvas.drawText("hello", 30, 100, paint);

paint.setARGB(100, 0, 255, 0);
canvas.drawText("hello", 30, 200, paint);

setShader

Shader 这个英文单词很多人没有见过,它的中文叫做「着色器」,也是用于设置绘制颜色的。「着色器」不是 Android 独有的,它是图形领域里一个通用的概念,它和直接设置颜色的区别是,着色器设置的是一个颜色方案,或者说是一套着色规则。当设置了 Shader 之后,Paint 在绘制图形和文字时就不使用 setColor/ARGB() 设置的颜色了,而是使用 Shader 的方案中的颜色。

PorterBuff.Mode

  • 目标图:指底板图
  • 源图:指即将画上的图

LinearGradient 线性渐变

在这里插入图片描述

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    int redColor = Color.RED;
    int greenColor = Color.GREEN;
    //x0 y0 x1 y1:渐变的两个端点的位置
    //color0 color1 是端点的颜色
    //tileMode 辐射辐射范围外的着色模式:CLAMP:端点外延续颜色;MIRROR:镜像模式;REPEAT:重复模式;
    Shader shader = new LinearGradient(100, 100, 500, 500, redColor, greenColor, Shader.TileMode.CLAMP);
    paint.setShader(shader);
    canvas.drawCircle(300, 300, 200, paint);
}

RadialGradient 辐射渐变

在这里插入图片描述

Shader shader = new RadialGradient(300, 300, 200, redColor, greenColor, Shader.TileMode.CLAMP);
paint.setShader(shader);
canvas.drawCircle(300, 300, 200, paint);

SweepGradient 扫描渐变

在这里插入图片描述

Shader shader = new SweepGradient(300, 300, redColor, greenColor);
paint.setShader(shader);
canvas.drawCircle(300, 300, 200, paint);

BitmapShader 位图填充

在这里插入图片描述

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
canvas.drawCircle(300, 300, 200, paint);

ComposeShader 混合着色器

在这里插入图片描述

Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.a);
Bitmap srcBitmap = Bitmap.createScaledBitmap(bitmap1, 400, 400, true);
Shader shader1 = new BitmapShader(srcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.b);
Bitmap dstBitmap = Bitmap.createScaledBitmap(bitmap2, 400, 400, true);
Shader shader2 = new BitmapShader(dstBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

ComposeShader shader = new ComposeShader(shader1, shader2, PorterDuff.Mode.DST_OUT);
paint.setShader(shader);

canvas.drawRect(0, 0, 400, 400, paint);

setColorFilter

ColorFilter 这个类,它的名字已经足够解释它的作用:为绘制设置颜色过滤。颜色过滤的意思,就是为绘制的内容设置一个统一的过滤策略,然后 Canvas.drawXXX() 方法会对每个像素都进行过滤后再绘制出来。

LightingColorFilter 光照效果

LightingColorFilter 的构造方法是 LightingColorFilter(int mul, int add) ,参数里的 muladd 都是和颜色值格式相同的 int 值,其中 mul 用来和目标像素相乘,add 用来和目标像素相加:

R' = R * mul.R / 0xff + add.R
G' = G * mul.G / 0xff + add.G
B' = B * mul.B / 0xff + add.B
R' = R * mul.R / 0xff + add.R

一个「保持原样」的「基本 LightingColorFilter 」,mul0xffffffadd0x000000(也就是0),那么对于一个像素,它的计算过程就是:

R' = R * 0xff / 0xff + 0x0 = R // R' = R
G' = G * 0xff / 0xff + 0x0 = G // G' = G
B' = B * 0xff / 0xff + 0x0 = B // B' = B

在这里插入图片描述

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
ColorFilter lightingColorFilter = new LightingColorFilter(0x00ffff, 0x000000);
paint.setColorFilter(lightingColorFilter);
canvas.drawBitmap(bitmap, 10, 10, paint);

关于ColorFilter的其他博客

在这里插入图片描述

setXfermode

Xfermode 指的是你要绘制的内容和 Canvas的目标位置的内容应该怎样结合计算出最终的颜色。但通俗地说,其实就是要你以绘制的内容作为源图像,以 View 中已有的内容作为目标图像,选取一个 PorterDuff.Mode 作为绘制内容的颜色处理方案。

使用Xfermode需要设置离屏缓冲

API说明
ComposeShader混合两种Shader
PorterBuffColorFilter增加一个单色的ColorFilter
Xfermode绘制图层和底部图层的混合计算方式

在这里插入图片描述

private Paint paint;
private RectF bounds;
private Bitmap circleBitmap;
private Bitmap squareBitmap;

private void init() {
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    bounds = new RectF(0, 0, 300, 300);
    circleBitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888);
    squareBitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(circleBitmap);
    paint.setColor(Color.RED);
    canvas.drawCircle(100, 100, 100, paint);

    canvas.setBitmap(squareBitmap);
    paint.setColor(Color.BLUE);
    canvas.drawRect(100, 100, 300, 300, paint);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    //设置离屏缓冲
    //离屏缓冲比较消耗资源。可以设置bounds指定区域
    int saved = canvas.saveLayer(bounds, null);

    //绘制dst
    canvas.drawBitmap(circleBitmap, 0, 0, paint);//画圆形

    //绘制src
    Xfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
    paint.setXfermode(xfermode);
    canvas.drawBitmap(squareBitmap, 0, 0, paint);//画矩形

    paint.setXfermode(null);//及时清理Xfermode
    //恢复
    canvas.restoreToCount(saved);
}
这篇关于Android 自定义View-Paint的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!