GradientDrawable与ShapeDrawable

作者: waiwaaa | 来源:发表于2021-05-29 14:57 被阅读0次

    引言:常规shape的用法

    当我们在Android项目中画一个圆角矩形的时候,我们通常会这样先在res/drawable里建一个drawable resouce file,比如round_rect.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <solid android:color="@color/colorPrimary"/>
        <corners android:radius="10dp"/>
    </shape>
    

    然后在xml中设置给xml,或都直接用Drawable draw = getResources().getDrawable(R.drawable.round_rect);来实例化后使用。一直以来,我以为shape对应的是ShapeDrawable,然而我打个断点,看到的却是这样的

    drawable的查看

    没错,xml中的shape被解析后实例化的是GradientDrawable,不相信的具体可以去查看源码。

    GradientDrawable实例化用法

    当计设图里有很多圆角背景,但我们又不相创造那么多xml的时候,就可以用GradientDrawable来实例化对象。

    /**
         * @param roundRadius
         *            圆角幅度
         * @param bgfillColor
         *            背景填充色
         * @param bgfillColorAlpha
         *            背景填充色透明度 double类型范围(0 ~ 1)
         * @param strokeWidth
         *            边框宽度 (0 无边框)
         * @param strokeColor
         *            边框颜色
         * @return
         */
        public static GradientDrawable myCustomShape(int roundRadius,
                int bgfillColor, double bgfillColorAlpha, int strokeWidth,
                int strokeColor) {
            GradientDrawable gradientDrawable = new GradientDrawable();
            if (0 != bgfillColorAlpha) {// 设置为0 则为全透明 不需要设置以下参数
                gradientDrawable.setColor(bgfillColor);
                gradientDrawable.setAlpha((int) (bgfillColorAlpha * 255));
            }
            gradientDrawable.setCornerRadius(roundRadius);
            gradientDrawable.setStroke(strokeWidth, strokeColor == 0 ? bgfillColor
                    : strokeColor);
            return gradientDrawable;
        }
    

    当然你也可以给每个角设置不同的圆角弧度,如果是有两种状态的,则可以用StateListDrawable,比如

    /**
         * // 1、2两个参数表示左上角,3、4表示右上角,5、6表示右下角,7、8表示左下角
         * @param nor_bg
         * @param nor_stroke
         * @param sel_bg
         * @param sel_stroke
         * @param topLeft
         * @param bottomLeft
         * @param topRight
         * @param bottomRight
         * @return
         */
        public static Drawable getDrawable(int nor_bg,int nor_stroke,int sel_bg,int sel_stroke, int topLeft, int bottomLeft, int topRight,
                int bottomRight){
            StateListDrawable bg = new StateListDrawable();
            GradientDrawable normal_drawable = new GradientDrawable();
            normal_drawable.setColor(nor_bg);
            normal_drawable.setCornerRadii(new float[] { topLeft, topLeft,
                    topRight, topRight, bottomRight, bottomRight, bottomLeft,
                    bottomLeft });
            normal_drawable.setStroke(Util.toDip(1), sel_stroke);
    
            GradientDrawable checked_drawable = new GradientDrawable();
            checked_drawable.setColor(sel_bg);
            checked_drawable.setCornerRadii(new float[] { topLeft, topLeft,
                    topRight, topRight, bottomRight, bottomRight, bottomLeft,
                    bottomLeft });
            checked_drawable.setStroke(Util.toDip(1), sel_stroke);
    
            bg.addState(new int[] { android.R.attr.state_checked },
                    checked_drawable);
            bg.addState(new int[] {}, normal_drawable);
            return bg;
        }
    

    更多的属性大家可以根据需要自己进行封装。

    ShapeDrawable实例化用法

    说完GradientDrawable,我们来看一下ShapeDrawable怎么用呢。其实在没有用GradientDrawable之前,我是一直在用ShapeDrawable来写这种背景的

    static public ShapeDrawable getRoundRect(int color,float roundLeftTop,float roundRightTop,float roundRightBottom,float roundLeftBottom){
            ShapeDrawable shapeDrawable = new ShapeDrawable();
            float[] outRadii=new float[]{roundLeftTop,roundLeftTop,roundRightTop,roundRightTop,roundRightBottom,roundRightBottom,roundLeftBottom,roundLeftBottom};
            RoundRectShape shape=new RoundRectShape(outRadii,null,null);
    
            shapeDrawable.setShape(shape);
            shapeDrawable.getPaint().setColor(color);
            return shapeDrawable;
        }
    

    有没有发现RoundRectShape 第二个第三个参数传的都是null.
    public RoundRectShape(@Nullable float[] outerRadii, @Nullable RectF inset, @Nullable float[] innerRadii) 这个类一共有3个参数,我在上面的注解已经说明了.

    注意!这3个参数都是可以为null的.意思就是,你可以取消任意一个.获得一些其他效果,比如设置第二个和第三个参数为null,你就可以得到一个实心的圆角矩形.

    如果你给后两个参数设置了,效果图大概是这个样子:


    image.png

    innerRadii 比较好理解就是圆角的弧度,inset 代表的是图里面黑色部分的厚度,中间白色的部分其实是父对象的背景。

    ShapeDrawable除了可以画GradientDrawable能画的纯色图外,还可以画很多别的图形,比如扇形,或者是自定义的path图。更多关于ShapeDrawable用法可以参考Android开发 ShapeDrawable详解

    相关文章

      网友评论

        本文标题:GradientDrawable与ShapeDrawable

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