Android Shader的学习

作者: 皮球二二 | 来源:发表于2016-06-21 16:10 被阅读1236次

    Shader是一个很基础也很简单的功能,在自定义View中的使用频率很高。我们日常所见的各种圆角、圆形头像、多彩环形图都会出现他们的身影

    圆角头像 圆形头像 多彩环形图

    基本概念

    Shader类主要是渲染图像以及一些几何图形,目前有5个直接的子类

    1. BitmapShader : 主要用来渲染图像
    2. LinearGradient : 用来进行线性渲染
    3. RadialGradient : 用来进行环形渲染
    4. SweepGradient : 扫描渐变---围绕一个中心点扫描渐变就像电影里那种雷达扫描,用来梯度渲染。
    5. ComposeShader : 组合渲染,可以和其他几个子类组合起来使用。

    TileMode类主要是在渲染器超出原始边界范围的时候,设置平铺的模式

    1. CLAMP:复制范围内边缘进行染色。
    2. REPEAT:横向和纵向的重复渲染器图片,平铺。
    3. MIRROR:横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺。

    还有2个主要的方法

    1. boolean getLoaclMatrix(Matrix localM)
      如果shader有一个非本地的矩阵将返回true。localM:如果不为null将被设置为shader的本地矩阵.
    2. **void setLocalMatrix(Matrix localM); **
      设置shader的本地矩阵,如果localM为空将重置shader的本地矩阵。

    实战

    接下来我们将通过学习,来了解如何通过Shader来实现这三个功能

    • 圆角、圆形头像
    @Overrideprotected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width=getMeasuredWidth();
        int height=getMeasuredHeight();
        Matrix matrix=new Matrix();
        Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.mipmap.bg_banner);
        int bmpWidth=bmp.getWidth();
        int bmpHeight=bmp.getHeight();
        float scale=(float) height/bmpHeight<(float) width/bmpWidth?(float) width/bmpWidth:(float) height/bmpHeight;
        matrix.postScale(scale, scale);
        matrix.postTranslate(-(bmpWidth*scale/2-getMeasuredWidth()/2), -(bmpHeight*scale/2-getMeasuredHeight()/2));
        BitmapShader shader=new BitmapShader(bmp, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        shader.setLocalMatrix(matrix);
        Paint paint=new Paint();
        paint.setAntiAlias(true);
        paint.setShader(shader);
        if (width==height) {
            canvas.drawCircle(getMeasuredWidth()/2, getMeasuredHeight()/2, getMeasuredWidth()<getMeasuredHeight()?getMeasuredWidth()/2:getMeasuredHeight()/2, paint);
        }
        else {
            canvas.drawRoundRect(new RectF(10, 10, width-10, height-10), 10, 10, paint);
        }
    }
    

    计算不同图片的宽高,然后缩放平移到中心点

    效果图
    • 多彩环形图
    int width=getMeasuredWidth();
    int height=getMeasuredHeight();
    Paint paint=new Paint();
    paint.setAntiAlias(true);
    paint.setColor(Color.LTGRAY);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(20);
    canvas.drawCircle(width/2, height/2, width/2-20/2, paint);
    int[] arcColors = new int[] {
            0xFF09F68C,
            0xFFB0F44B,
            0xFFE8DD30,
            0xFFF1CA2E,
            0xFFFF902F,
            0xFFFF6433,
            0xFF09F68C};
    SweepGradient sweepGradient=new SweepGradient(getMeasuredWidth()/2, getMeasuredHeight()/2, arcColors, null);
    paint.setColor(Color.WHITE);
    paint.setStrokeWidth(10);
    PathEffect effects = new DashPathEffect(new float[] { 2, 4, 8, 16}, 20);
    paint.setPathEffect(effects);
    paint.setShader(sweepGradient);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    canvas.drawArc(new RectF(10, 10, width-10, height-10), -90, 270, false, paint);
    

    使用SweepGradient可以直接画出圆弧,DashPathEffect可以画出虚线


    效果图

    OK,今天的东西就这么多,是不是很简单,以后在色彩上的需求,我们就可以轻松解决了

    相关文章

      网友评论

        本文标题:Android Shader的学习

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