自定义View绘图篇(二)-Paint

1、常用方法

方法 描述 方法 描述
setARGB 设置绘制的颜色,a代表透明 setAlpha 设置绘制图形的透明度
setColor 设置绘制的颜色 setAntiAlias 设置是否使用抗锯齿功能,会消耗资源
setDither 是否使用图像抖动处理,图片平滑和清晰 setStyle 设置画笔的样式,如FILL,FILL_OR_STROKE,或STROKE
setStrokeWidth 设置笔刷的粗细度 setStrokeCap 设置笔刷的图形样式, 如圆Cap.ROUND,或方形样式Cap.SQUARE
setFilterBitmap 是否在图像进行动画时滤掉对Bitmap图像的优化操作 setSrokeJoin 设置接合处的状态,MITER(锐角)、ROUND(圆弧)、BEVEL(直线)
setTextSize 设置绘制文字的字号大小 setTextColor 设置文字颜色
setTextAlign 设置绘制文字的对齐方向 setTextScaleX 设置绘制文字x轴的缩放比例
setTextSkewX 设置斜体文字,skewX为倾斜弧度 setUnderlineText 设置带有下划线的文字效果
setStrikeThruText 设置带有删除线的效果 setFakeBoldText 模拟实现粗体文字,设置在小字体上效果会非常差

2、设置字体setTypeface

Typeface:

  • BOLD:加粗

  • ITALIC:斜体

  • BOLD_ITALIC:粗斜体

  • NORMAL:正常

  • DEFAULT:默认正常字体对象

  • DEFAULT_BOLD:默认的字体对象,注意:这实际上不可能是粗体的,这取决于字体设置。 由getStyle()来确定

  • MONOSPACE:monospace 字体风格

  • SANS_SERIF:sans serif字体风格

  • SERIF:serif字体风格

  • 自定义,将我们的TTF文件,防到assets/font/目录下

    Typeface typeFace =Typeface.createFromAsset(getAssets(),"font/MONACO.ttf");

使用:

paint.setTypeface(Typeface.DEFAULT);

3、文字基线

计算文本的垂直方向的中间线与所占布局中间线的偏移量的方法为:

tip 内容引用自https://www.jianshu.com/p/15b8163ee8e7

image

其中baseline为基线,基线以上为负值,以下为正值。即top, ascent为负值,descent, bottom为正值。

image

4、实现滤镜效果setMaskFilter

4.1、BlurMaskFilter(模糊)

构造方法:

BlurMaskFilter(float radius, Blur style)
  • radius:指定模糊边缘的半径;
  • style:指定模糊的风格:
    • BlurMaskFilter.Blur.NORMAL:内外模糊
    • BlurMaskFilter.Blur.OUTER:外部模糊
    • BlurMaskFilter.Blur.INNER:内部模糊
    • BlurMaskFilter.Blur.SOLID:内部加粗,外部模糊
BlurMaskFilter bmf = new BlurMaskFilter(10f, BlurMaskFilter.Blur.OUTER);
paint.setMaskFilter(bmf);
canvas.drawText("我是一段模糊的文本~", 100, 100, paint);

setLayerType(View.LAYER_TYPE_SOFTWARE, null);     //关闭硬件加速

4.2、EmbossMaskFilter(浮雕)

通过指定环境光源的方向和环境光强度来添加浮雕效果,是图片更具与立体效果

EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)

  • direction:浮点型数组,用于控制x,y,z轴的光源方向
  • ambient:设置环境光亮度,0到1之间
  • specular:镜面反射系数
  • blurRadius:模糊半径
float[] direction = new float[]{ 1, 1, 3 };   // 设置光源的方向
float light = 0.4f;     //设置环境光亮度
float specular = 8;     // 定义镜面反射系数
float blur = 3.0f;      //模糊半径
EmbossMaskFilter emboss=new EmbossMaskFilter(direction,light,specular,blur);
paint.setMaskFilter(emboss);
canvas.drawText("我是一段具有浮雕效果的文本~", 100, 100, paint);

setLayerType(View.LAYER_TYPE_SOFTWARE, null);     //关闭硬件加速

5、图形重叠处理setXfermode

注意事项:

关闭硬件加速

再API 11后,在程序集中加入了对GPU的支持,而当我们的targetSdkVersion >= 14以上版本都是默认开启硬件加速的,而有些函数是不支持硬件加速的,因此需要关闭,关闭方式有以下三种:

  • Application:在配置文件的application节点添加: android:hardwareAccelerated="true"
  • Activity:在配置文件的activity节点添加 android:hardwareAccelerated="false"
  • 可以获得View对象后调用,或者直接在View的onDraw()方法里设置:
    view.setLayerType(View.LAYER_TYPE_HARDWARE, null);

使用离屏缓冲

saveLayer绘图流程:

这是因为在调用saveLayer时,会生成了一个全新的bitmap,这个bitmap的大小就是我们指定的保存区域的大小,新生成的bitmap是全透明的,在调用saveLayer后所有的绘图操作都是在这个bitmap上进行的。若没有设置,我们先把整个画布给染成了绿色,然后再画上了一个圆形,所以在应用xfermode来画源图像的时候,目标图像当前Bitmap上的所有图像了,也就是整个绿色的屏幕和一个圆形了。所以这时候源图像的相交区域是没有透明像素的,透明度全是100%,即saveLayer是为了区分哪一步的图形应该与合成模式和Bitmap去合成。

 int saved = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
 canvas.restoreToCount(saved);

处理方式:

这里涉及2个概念:源图像(SRC):图上黄色圆形,目标图形(DST):图上蓝色矩形。先设置重叠处理模式,再绘制时先绘制源图像,再绘制目标图形,会形成下面不同结果。

  • CLEAR:所绘制不会提交到画布上,会清除图像
  • SRC:显示上层绘制图片
  • DST:显示下层绘制图片
  • SRC_OVER:正常绘制显示,上下层绘制叠盖,正常显示。
  • DST_OVER:上下层都显示,下层居上显示。
  • SRC_IN:取两层绘制交集,显示上层(常用)。
  • DST_IN:取两层绘制交集,显示下层(常用)。
  • SRC_OUT:取上层绘制非交集部分(常用)。
  • DST_OUT:取下层绘制非交集部分(常用)。
  • SRC_ATOP:取下层非交集部分与上层交集部分
  • DST_ATOP:取上层非交集部分与下层交集部分
  • XOR:上层与下层交集部分不绘制
  • DARKEN:变暗,较深的颜色覆盖较浅的颜色,若两者深浅程度相同则混合
  • LIGHTEN:变亮,与DARKEN相反,DARKEN和LIGHTEN生成的图像结果与Android对颜色值深浅的定义有关
  • MULTIPLY:正片叠底,下层图像素颜色值乘以上层图像素颜色值除以255得到混合后图像像素颜色值
  • SCREEN:滤色,色调均和,保留两个图层中较白的部分,较暗的部分被遮盖

5.1、实现刮刮卡

思路:

  1. 使用Canvas绘制背景,以及展示给用户的中奖信息。
  2. 创建一个Bitmap用于保存给予用户展示的灰色层以及处理用户触摸path路径的交互。
  3. 将bitmap绘制Canvas中达到效果。

tip:做一个遮盖层,然后随着用户的刮开透明,完整代码:快速传送门。

6、设置渐变

 setShader(Shader shader) 

6.1、线性渐变

LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile) 。

参数:

  • x0,y0,x1,y1:渐变的两个端点的位置`

  • color0,color1:是端点的颜色

  • tile:端点范围之外的着色规则

    • CLAMP:延续渐变
    • MIRROR:镜像渐变
    • REPEAT:重复渐变
    Shader shader= new LinearGradient(0,60,100,60, Color.BLUE,
      Color.RED, Shader.TileMode.CLAMP);
    mPaint.setShader(shader);
    canvas.drawRect(0,0,300,150,mPaint);
    
    Shader shader1= new LinearGradient(0,160,100,160, Color.BLUE,
      Color.RED, Shader.TileMode.MIRROR);
    mPaint.setShader(shader1);
    canvas.drawRect(0,200,300,350,mPaint);
    
    Shader shader2= new LinearGradient(0, 460, 100, 460, Color.BLUE,
      Color.RED, Shader.TileMode.REPEAT);
    mPaint.setShader(shader2);
    canvas.drawRect(0, 400, 300, 550,mPaint);
    

6.2、辐射渐变

中心向周围辐射状的渐变

RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, TileMode tileMode)。

参数:

  • centerX centerY:辐射中心的坐标
  • radius:辐射半径
  • centerColor:辐射中心的颜色
  • edgeColor:辐射边缘的颜色
  • tileMode:辐射范围之外的着色模式。

6.3、扫描渐变

SweepGradient(float cx, float cy, int color0, int color1)

参数:
cx cy :扫描的中心
color0:扫描的起始颜色
color1:扫描的终止颜色

Shader shader = new SweepGradient(300, 300, Color.BLUE, Color.RED);
        mPaint.setShader(shader);
        canvas.drawCircle(300, 300, 200, mPaint);

6.4、BitmapShader

Bitmap 的像素来作为图形或文字的填充

BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)

参数:

  • bitmap:用来做模板的 Bitmap 对象
  • tileX:横向的 TileMode
  • tileY:纵向的 TileMode
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.scratch);
        Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
canvas.drawCircle(300, 300, 200, mPaint);
1539423445652.png

7、路径样式

设置路径样式

setPathEffect(PathEffect effect)

7.1、圆形拐角效果

CornerPathEffect(float radius)

参数:

  • 拐角圆的半径
path.moveTo(100, 100);
path.lineTo(200,200);
path.lineTo(400, 100);
path.lineTo(400, 400);
path.lineTo(600, 100);
mPaint.setPathEffect(new CornerPathEffect(100));
canvas.drawPath(path, mPaint);

7.2、虚线效果

DashPathEffect(float intervals[], float phase)

参数:

  • intervals[]:组成虚线的各个线段的长度(长度必须大于等于2,个数必须为偶数
  • phase:开始绘制的偏移值
//.........
mPaint.setPathEffect(new DashPathEffect(new float[]{5,5},2));
canvas.drawPath(path, mPaint);

7.3、离散路径效果

DiscretePathEffect(float segmentLength, float deviation)

参数:

  • segmentLength:示将原来的路径切成多长的线段,值越小,切得线段也越多
  • deviation:表示被切成的每个小线段的可偏移距离
//.......
mPaint.setPathEffect(new DiscretePathEffect(4,5));
canvas.drawPath(path, mPaint);

7.4、Path形状效果

PathDashPathEffect(Path shape, float advance, float phase,Style style)

参数:

  • shape:表示印章路径,如三角,点等;

  • advance:表示两个印章路径间的距离,很容易理解,印章间距离越大,间距就越大。

  • phase:路径绘制偏移距离

  • style:表示在遇到转角时,如何操作印章以使转角平滑过渡,取值有:Style.ROTATE(旋转)、Style.MORPH(变形)、Style.TRANSLATE(位移);

path.moveTo(100, 100);
path.lineTo(200,200);
path.lineTo(400, 100);
path.lineTo(400, 400);
path.lineTo(600, 100);

Path stampPath = new Path();
stampPath.moveTo(0, 20);
stampPath.lineTo(10, 0);
stampPath.lineTo(20, 20);
stampPath.close();
stampPath.addCircle(0, 0, 3, Path.Direction.CCW);

mPaint.setPathEffect(new PathDashPathEffect(stampPath, 35, 0, PathDashPathEffect.Style.TRANSLATE));
canvas.drawPath(path, mPaint);

你可能感兴趣的:(自定义View绘图篇(二)-Paint)