美文网首页自定义控件
高级UI<第十九篇>:Android之高级渲染Shader

高级UI<第十九篇>:Android之高级渲染Shader

作者: NoBugException | 来源:发表于2019-11-28 21:49 被阅读0次

Shader可分为5种,分别是BitmapShader(位图图像渲染)、LinearGradient(线性渲染)、SweepGradient(渐变渲染/梯度渲染)、RadialGradient(环形渲染)、ComposeShader(组合渲染)

(1)BitmapShader:位图图像渲染

BitmapShader作用于Bitmap,用Bitmap对绘制的图形进行渲染。
就以这个图片为例

pic.jpg

构造函数中需要传入图片的拉升模式TileMode,同时设置不同TileMode会展示的效果。

BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY)

BitmapShader构造方法有三个参数,第一个参数是bitmap图像,第二个参数是x方向拉伸方式,第三个参数是y方向拉伸方式。

代码如下

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.pic);

    mShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    //调用Paint的setShader(Shader shader)方法设置BitmapShader
    mPaint.setShader(mShader);
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    int width = getWidth() * 2 / 3;
    int height = getHeight() / 2; //使用设置了Shader的Paint进行绘制
    canvas.drawRect(0,0,width,height,mPaint);
}

随着修改拉伸方式,图像所展示的效果不同

  • TileMode.CLAMP:拉伸最后一个像素铺满。
图片.png
  • TileMode.MIRROR:镜像平铺


    图片.png
  • TileMode.REPEAT:重复平铺

图片.png

在现实项目中,往往我们会接到绘制圆形头像之类的需求,那么我们可以使用BitmapShader来实现

代码如下:

    mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.pic);
    BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
    mPaint.setShader(bitmapShader);
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    int radius = Math.min(mBitmap.getWidth(), mBitmap.getHeight()) / 2;

    canvas.drawCircle(radius, radius, radius, mPaint);

    RectF rectf = new RectF();
    rectf.left = 0;
    rectf.top = radius * 3;
    rectf.right = mBitmap.getWidth() / 2;
    rectf.bottom = radius * 3 + mBitmap.getHeight();
    canvas.drawOval(rectf, mPaint);
}

效果如下:

图片.png

(2)LinearGradient:线性渲染

它的渲染方式是线性的,顾名思义就是沿着一条线段进行渲染

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

前四个参数是确定线段的两点位置,后面分别是颜色、位置、拉伸模式。

代码如下

mPaint = new Paint();
mPaint.setAntiAlias(true);
LinearGradient mLinearGradient = new LinearGradient(0,300,300,300,new int[]{Color.RED,Color.BLUE,Color.RED,Color.BLUE},new float[]{0f, 0.3f, 0.6f, 0.7f}, Shader.TileMode.CLAMP);
mPaint.setShader(mLinearGradient);
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawRect(0,0,300,300,mPaint);
}

效果如下

图片.png

其中大致位置我已经标出

图片.png

(3)SweepGradient:渐变渲染/梯度渲染

它是以某个基准点开始,360度向周围渐变的渲染机制(类似于雷达、钟表)

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

前两个参数是某个点, 后面参数分别是颜色、位置。

代码如下

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    SweepGradient mSweepGradient = new SweepGradient(250, 250, new int[]{Color.GREEN, Color.YELLOW, Color.RED, Color.BLACK}, new float[]{0.0f,0.5f,0.8f,1f});
    mPaint.setShader(mSweepGradient);
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawCircle(250, 250, 250, mPaint);
}

效果如下:

图片.png

(4)RadialGradient:环形渲染

RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, TileMode tileMode)
RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, TileMode tileMode)

前两个参数是圆心点,后面的参数分别是圆的半径、位置、拉伸模式。

代码如下:

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    RadialGradient mRadialGradient = new RadialGradient(250, 250, 250, new int[]{Color.BLACK, Color.CYAN, Color.BLUE}, new float[]{0f, 0.9f, 1f}, Shader.TileMode.REPEAT);
    mPaint.setShader(mRadialGradient);
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawCircle(250, 250, 250, mPaint);
}

效果如下:

图片.png

(5)ComposeShader:组合渲染

ComposeShader会将两种渲染叠加。

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

代码如下:

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    LinearGradient mLinearGradient = new LinearGradient(0,300,300,300,new int[]{Color.RED,Color.BLUE,Color.RED,Color.BLUE},new float[]{0f, 0.3f, 0.6f, 0.7f}, Shader.TileMode.CLAMP);
    mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.pic);
    BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
    //ComposeShader composeShader = new ComposeShader(mLinearGradient, bitmapShader, PorterDuff.Mode.ADD);
    ComposeShader composeShader = new ComposeShader(mLinearGradient, bitmapShader, new PorterDuffXfermode(PorterDuff.Mode.ADD));
    mPaint.setShader(composeShader);
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawCircle(250, 250, 250, mPaint);
}

效果如下:

图片.png

[本章完...]

相关文章

网友评论

    本文标题:高级UI<第十九篇>:Android之高级渲染Shader

    本文链接:https://www.haomeiwen.com/subject/uqpiwctx.html