概述

Shader 是Android中非常重要的一个类 一般称之为着色器,其作用是用来给图像着色,我们一般在自定义View的时候通过paint.setShader(Shader shader)使用比较多 Shader有五个子类 下面将对每个API的使用做详细介绍

BitmapShader(图像渲染)

构造方法

public BitmapShader(@NonNull Bitmap bitmap, TileMode tileX, TileMode tileY)

该API是针对Bitmap进行绘制的 其参数含义

bitmap : 要进行绘制的bitmap
tileX : 在X轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPETA
tileY : 在Y轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPETA

这里对先对Shader.TileMode里有三种(拉伸)模式进行详解 后面的内容可以以此为参考(区分X轴和Y轴)

1.Shader.TileMode.CLAMP:

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.mipmap.mifeng)).getBitmap();    BitmapShader bitmapShader=new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);    paint.setShader(bitmapShader);    //画矩形图    canvas.drawRect(new RectF(0,0,1000,1200),paint);

Shader.TileMode.CLAMP会将边缘的像素进行拉伸、扩展到整个View的宽度或高度

2.Shader.TileMode.MIRROR(镜像)

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.mipmap.mifeng)).getBitmap();    BitmapShader bitmapShader=new BitmapShader(bitmap, Shader.TileMode.MIRROR,Shader.TileMode.MIRROR);    paint.setShader(bitmapShader);    //画矩形图    canvas.drawRect(new RectF(0,0,1000,1200),paint);

Shader.TileMode.MIRROR在绘制的矩形区域内,X轴方向和Y轴方向上出现了镜面翻转 直到占满整个View的宽高

3.Shader.TileMode.REPEAT(平铺):

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.mipmap.mifeng)).getBitmap();    BitmapShader bitmapShader=new BitmapShader(bitmap, Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);    paint.setShader(bitmapShader);    //画矩形图    canvas.drawRect(new RectF(0,0,1000,1200),paint);

Shader.TileMode.REPEAT 将图像进行复制平铺 跟电脑桌面壁纸一样 占不满一屏会进行平铺

另外通过BitmapShader自定义圆形或圆角矩形非常的简单

//构造函数一@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);      BitmapShader bitmapShader=new BitmapShader(bitmap, Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);        paint.setShader(bitmapShader);        //将图片通过矩阵拉伸为正方形        int max = Math.max(bitmapWidth, bitmapHeight);        int scale = max/ Math.min(bitmapWidth, bitmapHeight);        Matrix matrix=new Matrix();        matrix.setScale(scale,scale);        bitmapShader.setLocalMatrix(matrix);        //画圆形图        //canvas.drawCircle(max/2,max/2,max/2,paint);        //画椭圆形图        canvas.drawOval(new RectF(0,0,bitmapWidth,bitmapHeight),paint);   }
LinearGradient(线性渲染)

构造函数:

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

x0,y0:表示渐变的起点坐标x1,y1:表示渐变的终点坐标color0,color1:表示起点的颜色和终点的颜色。TileMode:和上面讲的完全一致,不赘述了。

LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],TileMode tile)

x0,y0:表示渐变的起点坐标x1,y1:表示渐变的终点坐标colors[]:传入多个颜色,产生更加丰富的渐变效果。float[]:可以设置在不同的渲染阶段渲染不同的颜色TileMode:和上面讲的完全一致,不赘述了。
//构造函数一@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);      LinearGradient linearGradient=new LinearGradient(0,0,1000,50,Color.RED,Color.BLUE,Shader.TileMode.REPEAT);      paint.setShader(linearGradient);      paint.setStyle(Paint.Style.FILL);      paint.setStrokeWidth(10);      canvas.drawRect(new RectF(10,10,1000,50),paint);   }
//构造函数二@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);      int[] mColors = {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW};      float[] loaction=new float[] {0.25F, 0.5F, 0.75F, 1.0F };      LinearGradient linearGradient=new LinearGradient(0,0,1000,50,mColors,loaction,Shader.TileMode.REPEAT);      paint.setShader(linearGradient);      paint.setStyle(Paint.Style.FILL);      paint.setStrokeWidth(10);      canvas.drawRect(new RectF(10,10,1000,50),paint);   }


提示:

  • 通过效果图看到在使用第二种方式创建对象的时候float[] loaction=new float[] {0.25F, 0.5F, 0.75F, 1.0F }的作用就是规划View每个绘制阶段绘制的颜色 比如在绘制0-25%的时候是红色 25%-50%是绿色 并以此类推
  • 另外需要注意的是float[] loaction的长度要与color[]的长度保持一致 且color[]的长度不得低于2 不然会报错 看源码就知道:
if (colors.length < 2) { throw new IllegalArgumentException("needs >= 2 number of colors");}if (positions != null && colors.length != positions.length){ throw new IllegalArgumentException("color and position arrays must be of equal length");}
RadialGradient(环形渲染,圆形中心向四周渐变的效果)

RadialGradient常用于水波纹效果
构造方法:

RadialGradient(float centerX, float centerY, float radius,
@NonNull int colors[], @Nullable float stops[], @NonNull TileMode tileMode)

这里的构造方法注意点与LinearGradient一致 这里不再赘述

centerX,centerY:表示渐变的起点坐标(中心点)radius:表示渐变半径长度colors[]:传入多个颜色,产生更加丰富的渐变效果。float[]:可以设置在不同的渲染阶段渲染不同的颜色TileMode:和上面讲的完全一致,不赘述了。

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

centerX,centerY:表示渐变的起点坐标(中心点)radius:表示渐变半径长度color0,color1:表示起点的颜色和终点的颜色。TileMode:和上面讲的完全一致,不赘述了。
@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    int[] mColors = {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW};    float[] loaction=new float[] {0.25F, 0.5F, 0.75F, 1.0F };    RadialGradient radialGradient=new RadialGradient(300,300,300,mColors,loaction,Shader.TileMode.CLAMP);    paint.setShader(radialGradient);    paint.setStyle(Paint.Style.FILL);    canvas.drawCircle(300,300,300,paint);   }
SweepGradient(梯度渲染)

SweepGradient类似于雷达扫描的效果

构造函数:

SweepGradient(float cx, float cy,int colors[], float positions[])

cx,cx:表示渐变的起点坐标(中心点)colors[]:传入多个颜色,产生更加丰富的渐变效果。float[]:与LinearGradient的positions[]效果一致 可以为null

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

cx,cx:表示渐变的起点坐标(中心点)color0,color1:开始颜色,结束颜色。
@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);   int[] mColors = {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW};   SweepGradient sweepGradient=new SweepGradient(300,300,mColors,null);   paint.setShader(sweepGradient);   canvas.drawCircle(300,300,300,paint);}

雷达效果(gif表现不怎么好 将就看下):


ComposeShader(组合模式)

构造函数:

ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)
ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode)

两个构造函数都差不多 将2个Shader进行混合渲染 只是最后一个参数指定了混合模式
关于混合模式可以参考:Android灵魂画家的18种混合模式

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Bitmap bitmap1 = ((BitmapDrawable)getResources().getDrawable(R.mipmap.heart)).getBitmap();        BitmapShader bitmapShader1=new BitmapShader(bitmap1, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        LinearGradient linearGradient1=new LinearGradient(0,0,bitmap1.getWidth(),bitmap1.getHeight(), Color.GREEN,Color.BLUE, Shader.TileMode.CLAMP);        //取两图层交集部分叠加后颜色        ComposeShader composeShader1=new ComposeShader(bitmapShader1,linearGradient1,PorterDuff.Mode.MULTIPLY);        paint.setShader(composeShader1);        canvas.drawRect(0,0,bitmap1.getWidth(),bitmap1.getHeight(),paint);        canvas.translate(0,200);        linearGradient1=new LinearGradient(0,0,bitmap1.getWidth(),bitmap1.getHeight(), Color.RED,Color.RED, Shader.TileMode.CLAMP);        //取两图层交集部分叠加后颜色        composeShader1=new ComposeShader(bitmapShader1,linearGradient1,PorterDuff.Mode.MULTIPLY);        paint.setShader(composeShader1);        canvas.drawRect(0,0,bitmap1.getWidth(),bitmap1.getHeight(),paint);}


关于Shader的相关基本使用方法就介绍到这里 另外Shader还支持各种矩阵操作 通过 setLocalMatrix(matrix)调用 哎 感觉一篇下来都在拼图 好累!

更多相关文章

  1. Android(安卓)NDK c创建java对象
  2. Android——实现渐变色水波纹效果源码
  3. ColorStateList按钮文字变色
  4. Android(安卓)标题栏和状态栏随ScrollView滑动颜色改变轻松实现
  5. Android(安卓)沉浸式状态栏 一体化状态栏实现
  6. Android(安卓)int颜色值和rgba颜色互转
  7. Android底部导航栏BottomNavigatonView的使用方式
  8. 改变ProgressBar默认颜色
  9. EditText背景 光标 下划线颜色

随机推荐

  1. Mac下配置Android(安卓)NDK环境并搭建
  2. 内容提供者相关技术
  3. Android(安卓)通知总结
  4. android surfaceflinger研究----Surface
  5. Android(安卓)SparseArray 分析
  6. Android(安卓)读取app内json配置文件
  7. 让Android手机变得无所不能-几种很有创意
  8. Android面试系列文章2018之Android部分As
  9. android 如何完全卸载Android(安卓)Studi
  10. Handler与异步消息处理