Android之玩转View(二):使用Paint实现的特效(BitmapShader,LinearGradient,RadialGradient,SweepGradient)

请尊重原创,转载请注明出处【tianyl】的博客

关于的Android之玩转View目录

1 前言

上一篇Paint的基础api介绍了Android中Paint这个类的一些比较常用的api,不过光说不练怎么行呢,这篇就结合之前介绍的api,来秀一秀可以实现的各种炫酷特效,话不多说,开工

2 Shader

要使用Paint实现一些高级特效,那么就少不了一个关键的类Shader

2.1 介绍

Shader在Android中又被称为着色器,字面意思就是用来上色的,它有很多的实现类BitmapShader,ComposeShader,LinearGradient,SweepGradient,RadialGradient,下面我们从简单到复杂一个一个的介绍这些类

2.1.1 BitmapShader

BitmapShader叫做位图图像渲染,用bitmap对绘制的图形进行渲染着色,简单来说是用图片对图形进行填充

  • 使用方法如下
//这里的mBitMap是我们准备绘制的图片
BitmapShader bitMapShader = new BitmapShader(mBitMap, Shader.TileMode.MIRROR,
        Shader.TileMode.MIRROR);
//设置shader
mPaint.setShader(bitMapShader);
//抗锯齿
mPaint.setAntiAlias(true);
//随意绘制一个范围的图像,mWidth和mHeight是mBitMap的宽高
canvas.drawRect(0, 0, mWidth*2, mHeight*2, mPaint);

上面代码就是一个BitmapShader使用的实例代码,方法一般写在onDraw方法中,通过继承View实现自定义的效果

  • 原图如下


  • 效果如下


在BitmapShader的构造方法中,有几个参数

  • TileMode.CLAMP 拉伸最后一个像素去铺满剩下的地方
  • TileMode.MIRROR 通过镜像翻转铺满剩下的地方
  • TileMode.REPEAT 重复图片平铺整个画面
public BitmapShader(
@NonNull Bitmap bitmap, 
@NonNull TileMode tileX, 
@NonNull TileMode tileY
)

第一个参数是需要绘制的bitmap,第二个参数是x轴方向的效果,第三个参数是y轴方向的效果

上图就是使用TileMode.MIRROR进行实现的,的使用它可以实现镜像的效果,当然如果加上渐变的透明度,就是一个很好看的水面倒影了

一个例子

说到BitmapShader,那么再说说一个很常见的功能——圆形图像/椭圆形图像

//使用需要绘制的mBitMap构造一个BitmapShader
BitmapShader bitMapShader = new BitmapShader(mBitMap, 0,0);
//构造一个ShapeDrawable,OvalShape是椭圆形
ShapeDrawable shapeDrawble = new ShapeDrawable(new OvalShape());
//将bitMapShader设置给ShapeDrawable
shapeDrawble.getPaint().setShader(bitMapShader);
//设置编辑,圆形就是这个矩形边界的内切圆,如果是正方形,那么就是圆形,反之则是椭圆
shapeDrawble.setBounds(0,0,mWidth,mWidth);
//绘制
shapeDrawble.draw(canvas);

我们知道圆形图像可以在xml中用shape实现,那么如何在代码中实现shape呢,答案就是ShapeDrawable

当然,这里我们不说ShapeDrawable,我们说用ShapeDrawable搭配BitmapShader实现的圆形头像

效果如下


2.1.2 LinearGradient

LinearGradient叫做线性渲染,常见的霓虹灯文字,倒影图片就是使用它进行实现的

线性渐变也是一个用得比较多的渐变,比较多的用法是颜色的渐变和透明度的渐变

构造方法如下

int[] mColors = {Color.RED,Color.YELLOW,Color.GREEN,Color.BLUE}
LinearGradient linearGradient = 
    new LinearGradient(0, 0, 400, 400, mColors, null, Shader.TileMode.MIRROR);
mPaint.setShader(linearGradient);
canvas.drawRect(0, 0, 800, 800, mPaint)
  • 前4个参数分别是 x0, y0, x1, y1 表示x轴起点,y轴起点,x轴终点,y轴终点
  • mColors是一个color数组,表示渐变的颜色,我这里分别是红,黄,绿,蓝
  • 第五个参数是一个float数组,表示每个颜色所对应的位置,也可以理解为每个颜色需要占总长度的多少,取值范围是从0到1,如果每个颜色的长度相同,即颜色均匀,则可以传null
  • 最后一个参数就是渐变模式了,和BitmapShader中一样,这里还是使用镜像模式(Shader.TileMode.MIRROR)

效果如下


上面说过了,线性渐变可以实现水面倒影效果,当然,还有透明度的渐变也是可以通过线性渐变实现的

SweepGradient

SweepGradient叫做扫描渲染(或者梯度渲染),就和它的名字一样,用它可以实现扫描效果

SweepGradient mSweepGradient = new SweepGradient(400, 400, mColors, null);
mPaint.setShader(mSweepGradient);
canvas.drawCircle(400, 400, 400, mPaint)

mColors还是使用的线性渐变中的颜色
效果如下


它是一个顺时针的渐变,如果我们旋转这张图,那就是一个简单的扫描效果了,这个比较简单,看图就懂,这里就不多说了

RadialGradient

RadialGradient叫做环形渲染,用它可以实现水波纹效果
如下是一个简单的环形渐变效果

RadialGradient mRadialGradient = 
    new RadialGradient(400, 400, 100, mColors, null, Shader.TileMode.REPEAT);
mPaint.setShader(mRadialGradient);
canvas.drawCircle(400, 400, 400, mPaint)

构造参数

  • 前2个分别是圆心的x坐标和y坐标
  • 第3个参数是渐变的半径,这里是100
  • 第4个是颜色,还是使用的线性渐变用过的颜色
  • 第5个参数和之前线性渐变一样,一个float数组,类似于权重的作用
  • 最后一个参数是渐变模式,这里是反复,即结束后重新开始

效果如下


ComposeShader

ComposeShader叫做组合渲染,它是将上面的任意两种渐变效果进行组合,看它的构造函数就可以明白

ComposeShader(Shader shaderA, Shader shaderB, int nativeMode) 

前两个参数分别是上面的任意两种渐变效果,第三个参数是一个PorterDuff.Mode常量

PorterDuff.Mode的总结很多,暂时放后面,这里就不引申了

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