我的自定义View学习笔记(二)—— Paint 使用

  • 这个一个系列,本系列讲的都是本人自定义 View 的学习笔记。目的是加深影响,便于在以后工作中遇到相关问题的时候,能够有个印象知道到哪里去寻找答案。
  • 这是我学习扔物线大神的自定义 View 教程,自己记录的笔记。链接在这里HenCoder,强烈推荐大家去原地址学习,毕竟我写的笔记只是针对我个人的口味而言的,用词和对概念的理解不一定有扔物线大神准确。
  • 我再发一次地址:https://hencoder.com

对 Paint 中的方法进行记录

  • Paint 的方法主要分为四类
    • 颜色
    • 效果
    • drawText()
    • 初始化

一、颜色

image

canvas 中有多种绘制颜色的方式。最后一种就涉及到本文章主要说的 Paint 的使用

  • drawColor/RGB/ARGB() 直接传入颜色
  • drawBitmap() 传入的是 bitmap 的颜色(并没觉得绘制图片和颜色有关系
  • drawCircle()、drawPath()、drawText() 等多种绘制方法,使用 paint 中的颜色

Paint中使用颜色

1、直接设置颜色

  • setColor(int color)
    • 直接传入 Color.parse("#000000") 括号内就是颜色的代码
  • setARGB(int a, int r, int g, int b)
    • 颜色的三原色传入

2、设置 Shader(着色器) 传入颜色

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        Shader linerGradient0 = new LinearGradient(0, 100, 200, 100,
                Color.parseColor("#E91E63"), Color.parseColor("#2196F3"),
                Shader.TileMode.CLAMP);
        paint.setShader(linerGradient0);
        canvas.drawCircle(100, 100, 100, paint);
  • 颜色渐变 Gradient
    • 线性渐变 LinearGradient
      • 定义两个点,从两点之间渐变
        Shader linerGradient0 = new LinearGradient(0, 100, 200, 100,
                Color.parseColor("#E91E63"), Color.parseColor("#2196F3"),
                Shader.TileMode.CLAMP);
- 辐射渐变 RadialGradient
    - 从中间向外,辐射型渐变
        Shader radialGradient0 = new RadialGradient(100, 350, 100,
                Color.parseColor("#E91E63"), Color.parseColor("#2196F3"),
                Shader.TileMode.CLAMP);
- 扫描渐变 SweepGradient
    - 扇面扫描类型的渐变
        Shader sweepGradient = new SweepGradient(300, 300, Color.parseColor("#E91E63"),
                Color.parseColor("#2196F3"));
        paint.setShader(sweepGradient);
- 其中线性线性渐变和辐射渐变有一个 TileMode 属性,CLAMP、MIRROR、REPEAT 三种样式 加载、镜像、重复模式
  • BitmapShader 对图片进行处理
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.batman);  
Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);  
paint.setShader(shader);
- 其中第二、三个参数,是决定水平和竖直方向上的图片显示模式同上
  • ComposeShader 混合着色器
    • 两种格式叠加使用,根据不同的 mode 格式,实现不同的叠加效果

3、颜色过滤

  • setColorFilter(ColorFilter colorFilter);
    • LightingColorFilter 模拟光照。通过计算之后,过滤某一颜色,使得在显示的时候是过滤之后的颜色
    • PorterDuffColorFilter、ColorMatrixColorFilter 同上,也是根据不用的计算方式显示不同的过滤颜色的方式
    • 该方法能实现多种图片颜色处理方式,例如各种常见的滤镜效果,用的时候再详细学习吧

4、颜色图形转化方式

  • 具体使用没看太懂。主要用途是图片叠加显示时的问题

二、效果

1、抗锯齿 setAntiAlias(boolean aa)

2、填充效果 setStyle(Paint.Style style)

  • 充满 Paint.Style.FILL
  • 划线 Paint.Style.StROKE
  • 填充加划线 Paint.Style.FILL_AND_STROKE

3、线条形状

  • setStrokeWidth(float width) 设置线条宽度

  • setStrokeCap(Paint.Cap cap) 设置线头的形状
    image

    • 平头 BUTT
    • 方头 ROUND
    • 圆头 SQUARE
  • setStrokeJoin(Paint.Join join) 设置拐角的形状
    image

    • Paint.Join.ROUND 圆角
    • Paint.Join.MITER 尖角
    • Paint.Join.BEVEL 平角
  • setStrokeMiter(float miter)

    • 对于拐角形状的补充

4、色彩优化

(1) setDither(boolean dither)
  • 抖动,优化色彩深度降低时的绘制效果。没什么卵用
(2)setFilterBitmap(boolean filter)
  • 双线性过滤。是图片绘制更平滑,减轻马赛克效果

5、setPathEffect(PathEffect effect)

  • 使用 PathEffect 来给图形的轮廓设置效果。
(1) CornerPathEffect
  • 把拐角设置成圆角
PathEffect pathEffect = new CornerPathEffect(20);  
paint.setPathEffect(pathEffect);
(2) DiscretePathEffect
  • 线条进行随机偏离,让轮廓变的乱七八糟
PathEffect pathEffect = new DiscretePathEffect(20, 5);  
paint.setPathEffect(pathEffect);
(3) DashPathEffect
  • 虚线线条,轮廓变成虚线
PathEffect pathEffect = new DashPathEffect(new float[]{20, 10, 5, 10}, 0);  
paint.setPathEffect(pathEffect);
  • 第一个参数 intervals是一个数组,它指定了虚线的格式:数组中元素必须为偶数(最少是 2 个),按照「画线长度、空白长度、画线长度、空白长度」……的顺序排列,例如上面代码中的 20, 5, 10, 5 就表示虚线是按照「画 20 像素、空 5 像素、画 10 像素、空 5 像素」的模式来绘制;第二个参数 phase 是虚线的偏移量。
(4) PathDashPathEffect
  • 自定义虚线的图形
        Path dashPath = new Path();
        dashPath.moveTo(0, 0);
        dashPath.lineTo(10, 0);
        dashPath.lineTo(5, 10);
        dashPath.close();
        PathEffect pathDashPathEffect = new PathDashPathEffect(dashPath, 40, 0,
                PathDashPathEffect.Style.ROTATE);
        paint.setPathEffect(pathDashPathEffect);
  • 第一个参数是虚线的图形、第二个参数是虚线之间的间距、第三个是偏移量
  • 第四个参数是虚线图形的拐弯时的样式
    • TRANSLATE:位移
    • ROTATE:旋转
    • MORPH:变体
      image
(5) SumPathEffect
  • 组合效果,将两种效果直接叠加到一起
        PathEffect sumPathEffect = new SumPathEffect(discretePathEffect, dashPathEffect);
        paint.setPathEffect(sumPathEffect);
(6) ComposePathEffect
  • 组合效果。是先对 View 进行第一次效果,然后再进行第二次效果
  • 效果的先后顺序也会影响最后的效果
        PathEffect composePathEffect = new ComposePathEffect(discretePathEffect, dashPathEffect);
        paint.setPathEffect(composePathEffect);
(7) 注意
  • PathEffect 在有些情况下不支持硬件加速,需要关闭硬件加速才能正常使用

6、setShadowLayer 绘制阴影

paint.setShadowLayer(20, 10, 10, Color.RED);
  • 第一个参数是阴影的模糊范围,第二、三个参数是阴影 x、y 方向偏移量,第四个参数是阴影颜色
  • 清除阴影使用 clearShadowLayer()
  • 在硬件加速开启的情况下,setShadowLayer()只支持文字的绘制,文字之外的绘制必须关闭硬件加速才能正常绘制阴影。
  • 如果 shadowColor 是半透明的,阴影的透明度就使用 shadowColor 自己的透明度;而如果 shadowColor 是不透明的,阴影的透明度就使用 paint 的透明度。

7、setMaskFilter(MaskFilter maskfilter) 绘制遮罩

  • setMaskFilter(MaskFilter maskfilter) 方法和 setShadowLayer() 方法正相反,是在 View 上层添加效果,相当于遮罩层
(1) BlurMaskFilter
MaskFilter blurMaskFilter = new BlurMaskFilter(50, BlurMaskFilter.Blur.OUTER);
  • 模糊效果
  • 第一个参数是模糊的范围
  • 第二个参数是模糊类型
    • NORMAL: 内外都模糊绘制
    • SOLID: 内部正常绘制,外部模糊
    • INNER: 内部模糊,外部不绘制
    • OUTER: 内部不绘制,外部模糊(什么鬼?)
      image
(2) EmbossMaskFilter
new EmbossMaskFilter(new float[]{0, 1, 1}, 0.2f, 8, 10)
  • 浮雕效果,具体的用到再说吧
此效果使用时,需要关闭硬件加速效果(基本也用不上吧)

8、获取绘制的 Path

  • 获取 Path 的绘制路径,我理解为复制源 Path 的样式
(1) Paint.getFillPath(Path src, Path dst)
  • 获取图形的路径轮廓,src 为源 Path,dst 为目标 Path
  • 在源 Path 的 Paint 为 STROKE 时
(2) getTextPath(String text, int start, int end, float x, float y, Path path) / getTextPath(char[] text, int index, int count, float x, float y, Path path)
  • 获取文字路径
  • 多用于对于文字的修饰效果

三、drawText() 相关

  • 对文字进行设置,间距、大小、字体、效果等功能。下一节

四、初始化类

  • 用来初始化 Paint 对象,或者批量设置 Paint 的多个属性方法

1、reset()

  • 相当于 new 一个 Paint

2、set(Paint src)

  • 把 src 的属性全部复制过来

3、setFlags(int flags)

  • 批量设置 Paint 的属性
paint.setFlags(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
等同于
paint.setAntiAlias(true);  
paint.setDither(true); 

猜你喜欢

转载自blog.csdn.net/Android_03/article/details/84072725