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:表示被切成的每个小线段的可偏移距离。值越大,就表示每个线段的可偏移距离就越大,就显得越凌乱,值越小,每个线段的可偏移原位置的距离就越小。
我们看下代码效果:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容