Android Paint之函数大汇总

厚积方能薄发

今天我们来个大汇总,列举一个 Paint 的所有函数,然后一个一个的过。经过这几篇,你将能学会Paint中所有处理函数的用法。

基本用法

函数 含义
reset() 重置画
setColor(int color) 给画笔设置颜色值
setARGB(int a, int r, int g, int b) 同样是设置颜色,但是利用ARGB分开设置
setAlpha(int a) 设置画笔透明度
setStyle(Paint.Style style) 设置画笔样式
setStrokeWidth(float width) 设置画笔宽度
setAntiAlias(boolean aa) 设置画笔是否抗锯齿

上面这些函数我们都讲过,下面来看看一些新的函数

setStrokeCap(Paint.Cap cap) 设置线冒样式,取值有Cap.ROUND(圆形线冒)、Cap.SQUARE(方形线冒)、Paint.Cap.BUTT(无线冒)

setStrokeJoin(Paint.Join join) 设置线段连接处样式,取值有:Join.MITER(结合处为锐角)、Join.Round(结合处为圆弧)、Join.BEVEL(结合处为直线)

setStrokeMiter(float miter) 设置笔画的倾斜度,90度拿画笔与30拿画笔,画出来的线条样式肯定是不一样的吧。(事实证明,根本看不出来什么区别好吗……囧……)

setPathEffect(PathEffect effect) 设置路径样式;取值类型是所有派生自PathEffect的子类:ComposePathEffect, CornerPathEffect, DashPathEffect, DiscretePathEffect, PathDashPathEffect, SumPathEffect

这四个函数中,setStrokeMiter(float miter)就不再讲了,我做过试验,没什么变化,也就是没啥屌用……,我们分别来看看另外三个函数的具体用法。

setStrokeCap(Paint.Cap cap)

设置线帽样式,取值有Cap.ROUND(圆形线帽)、Cap.SQUARE(方形线帽)、Paint.Cap.BUTT(无线帽)
我先不讲什么叫做线冒,大家先来看看下面这段代码以及它的效果:

package com.as.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

public class PaintView extends View {

    public PaintView(Context context) {
        this(context, null);
    }

    public PaintView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

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

        Paint paint = new Paint();
        paint.setStrokeWidth(120);
        paint.setAntiAlias(true);
        paint.setColor(Color.GREEN);
        paint.setStyle(Paint.Style.STROKE);


        paint.setStrokeCap(Paint.Cap.BUTT);
        canvas.drawLine(100, 200, 400, 200, paint);

        paint.setStrokeCap(Paint.Cap.SQUARE);
        canvas.drawLine(100, 400, 400, 400, paint);

        paint.setStrokeCap(Paint.Cap.ROUND);
        canvas.drawLine(100, 600, 400, 600, paint);

        paint.reset();
        paint.setStrokeWidth(2);
        paint.setColor(Color.RED);
        canvas.drawLine(100, 50, 100, 750, paint);
        canvas.drawLine(400, 50, 400, 750, paint);
    }
}

在这里,我们水平画了三条线,他们的线冒类型分别是Cap.BUTT(无线帽)、Cap.SQUARE(方形线帽)、Cap.ROUND(圆形线冒)
最后,垂直画出x=100的那条起始线,垂直画出x=400的那条起始线。



从效果图中可以明显看出,从无线冒多出来的那块区域就是线帽!就相当于给原来的直线加上一个帽子一样,所以叫线帽。android的线冒样式是很少的,只有方形和圆形两种。

setStrokeJoin(Paint.Join join)

  • Join.MITER(结合处为锐角)
  • Join.Round(结合处为圆弧)
  • Join.BEVEL(结合处为直线)

我们画出来三个锐角的path,分别给这三段Path设置不同的连接方式:

Paint paint = new Paint();
        paint.setStrokeWidth(60);
        paint.setColor(Color.GREEN);
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);

        Path path = new Path();
        path.moveTo(100, 100);
        path.lineTo(450, 100);
        path.lineTo(100, 300);
        paint.setStrokeJoin(Paint.Join.MITER);
        canvas.drawPath(path, paint);

        path.moveTo(100, 400);
        path.lineTo(450, 400);
        path.lineTo(100, 600);
        paint.setStrokeJoin(Paint.Join.BEVEL);
        canvas.drawPath(path, paint);

        path.moveTo(100, 700);
        path.lineTo(450, 700);
        path.lineTo(100, 900);
        paint.setStrokeJoin(Paint.Join.ROUND);
        canvas.drawPath(path, paint);

Join.Round和 Join.BEVEL没有明显的区别

setPathEffect(PathEffect effect)

设置路径样式;取值类型是所有派生自PathEffect的子类

我们一个个来看他们的效果:CornerPathEffect——圆形拐角效果,它的作用就是将原来Path生硬的直线拐角,变成圆形拐角

public CornerPathEffect(float radius)

它只有一个参数radius:即当前连接两条直线所使用的圆的半径。


上面这个图,很清晰的展示了利用半径R=50的圆来代替原来两条直线间的夹角。
我们利用代码,再来看看具体效果:

        Paint paint = new Paint();
        paint.setStrokeWidth(4);
        paint.setColor(Color.GREEN);
        paint.setStyle(Paint.Style.STROKE);

        Path path = new Path();
        path.moveTo(100,600);
        path.lineTo(400,100);
        path.lineTo(660,800);

        canvas.drawPath(path,paint);

        paint.setColor(Color.RED);
        paint.setPathEffect(new CornerPathEffect(100));
        canvas.drawPath(path,paint);

        paint.setColor(Color.BLUE);
        paint.setPathEffect(new CornerPathEffect(200));
        canvas.drawPath(path,paint);

在这里,我利用Path构造了一个夹角,在同一个位置画了三遍,第一遍是没有添加任何PathEffect的;第二遍,CornerPathEffect的圆半径为100;第三遍CornerPathEffect的圆半径为200;

很明显能看出在半径不同情况下,连接位置也是不一样的。

DashPathEffect——虚线效果

它的函数声名如下:

public DashPathEffect(float intervals[], float phase)
  • intervals[]:表示组成虚线的各个线段的长度;如果我们定义intervals[]为new float[] {20,10,100,100};那么这条虚线将是由四条子线段循环组成的,第一条实线长度为20,第二个空线长度为10,第三个实线长为100,第四条空线长充为100;长度必须大于等于2;因为必须有一个实线段和一个空线段来组成虚线。个数必须为偶数,如果是基数,最后一个数字将被忽略;这个很好理解,因为一组虚线的组成必然是一个实线和一个空线成对组成的。

  • phase:开始绘制的偏移值

我们来看看代码的运行效果来验证我们想的是否正确:

Paint paint = getPaint();
        Path path = new Path();
        path.moveTo(100, 600);
        path.lineTo(400, 100);
        path.lineTo(700, 900);

        canvas.drawPath(path, paint);
        paint.setColor(Color.RED);

        //使用DashPathEffect画线段
        paint.setPathEffect(new DashPathEffect(new float[]{20, 10, 100, 100}, 0));
        canvas.translate(0, 100);
        canvas.drawPath(path, paint);

        //画同一条线段,偏移值为15
        paint.setPathEffect(new DashPathEffect(new float[]{20, 10, 50, 100}, 15));
        paint.setColor(Color.BLUE);
        canvas.translate(0, 100);
        canvas.drawPath(path, paint);

其中把paint封装成一个getPaint方法来获取基本的画笔设置。

private Paint getPaint(){
    Paint paint = new Paint();
    paint.setStrokeWidth(4);
    paint.setColor(Color.GREEN);
    paint.setStyle(Paint.Style.STROKE);
    paint.setAntiAlias(true);
    return paint;
}

从这个效果图中可以看到两点:
第一:红线段的基本组成部分,分别长度为20,10,100,100实线段和空线段组成的
第二:黄线段位移了15,从开始处就可以明显看出效果。原来20的线段,只剩5,所以看起来就像一个点一样。

DiscretePathEffect——离散路径效果

同样,图中第一条线是原生的,第二条线加上离散路径效果后的样式。
DiscretePathEffect就是将原来路径分隔成定长的线段,然后将每条线段随机偏移一段位置,我们可以用它来模拟一种类似生锈铁丝的效果;
它的构造函数如下:

public DiscretePathEffect(float segmentLength, float deviation)

第一个参数segmentLength:表示将原来的路径切成多长的线段。如果值为2,那么这个路径就会被切成一段段由长度为2的小线段。所以这个值越小,所切成的小线段越多;这个值越大,所切成的小线段越少。
第二参数deviation:表示被切成的每个小线段的可偏移距离。值越大,就表示每个线段的可偏移距离就越大,就显得越凌乱,值越小,每个线段的可偏移原位置的距离就越小。
我们看下代码效果:

推荐阅读更多精彩内容