zoukankan      html  css  js  c++  java
  • 有关Color和Drawable你所不知道的那些内容

    Android开发中,我们经常会用到Color或Drawable,有时他们是可以混用的,有时却有严格的区别。

    Drawable

    体系结构

    Drawable是可绘制物件的一般抽象。与View不同,Drawable上没有事件和交互方法。我们经常会自定义View来实现一些复杂或绚丽的UI效果,其实也可以自定义Drawable来实现。 
    Drawable本身是一个抽象类,我们一般使用的是它的子类,都在android.graphics.drawable包下。有BitmapLevelsNinePatchScaleShapeLayersStates等等。

    原理

    draw(Canvas canvas)Drawable必须附在一个View上,绘制成什么样子,setBounds()来决定大小,由view的draw方法来绘制Drawable的子类。

    圆角和圆形Drawable(头像)

    自定义Drawable很容易实现圆角和圆形图片,先看效果图: 
    Round-Circle

    /**
     * 圆角图片
     * Created by dengpan on 16/4/21.
     */
    public class RoundRectImageDrawable extends Drawable {
    
        private RectF rectF;
    
        private Paint mPaint;
    
        private Bitmap bitmap;
    
        public RoundRectImageDrawable(Bitmap bitmap) {
            this.bitmap = bitmap;
            //表示图片太大,则填充。TileMode还有repeat、mirror,表示重复
            BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setShader(bitmapShader);
            rectF = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
        }
    
        @Override
        public void setBounds(int left, int top, int right, int bottom) {
            super.setBounds(left, top, right, bottom);
            rectF = new RectF(left, top, right, bottom);
        }
    
        @Override
        public void draw(Canvas canvas) {
            //60表示圆角的半径
            canvas.drawRoundRect(rectF, 60, 60, mPaint);
        }
    
        @Override
        public void setAlpha(int alpha) {
    
        }
    
        @Override
        public void setColorFilter(ColorFilter colorFilter) {
    
        }
    
        @Override
        public int getOpacity() {
            return 0;
        }
    
        //设置下面两个方法,保证原图可以完整的显示出来。
        @Override
        public int getIntrinsicWidth() {
            return bitmap.getWidth();
        }
        @Override
        public int getIntrinsicHeight() {
            return bitmap.getHeight();
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    下面是圆形Drawable:

    /**
     * 圆形图片(头像)
     * Created by dengpan on 16/4/21.
     */
    public class CircleDrawable extends Drawable {
    
        private int mWidth;
    
        private RectF rectF;
    
        private Paint mPaint;
    
        private Bitmap bitmap;
    
        public CircleDrawable(Bitmap bitmap) {
            this.bitmap = bitmap;
    
            BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setShader(bitmapShader);
            rectF = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
            mWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());
        }
    
        @Override
        public void setBounds(int left, int top, int right, int bottom) {
            super.setBounds(left, top, right, bottom);
            rectF = new RectF(left, top, right, bottom);
            mWidth = (int) Math.min(rectF.width(), rectF.height());
        }
    
        @Override
        public void draw(Canvas canvas) {
            canvas.drawCircle(rectF.left + mWidth / 2, rectF.top + mWidth / 2, mWidth / 2, mPaint);
        }
    
        @Override
        public void setAlpha(int alpha) {
    
        }
    
        @Override
        public void setColorFilter(ColorFilter colorFilter) {
    
        }
    
        @Override
        public int getOpacity() {
            return 0;
        }
    
    
        //设置了下面两个方法的返回值,才能正常的显示完整的圆形头像,不然头像太大,就截取了左上角部分。
        @Override
        public int getIntrinsicWidth() {
            return mWidth;
        }
    
        @Override
        public int getIntrinsicHeight() {
            return mWidth;
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    调用方法:

    Bitmap b = BitmapFactory.decodeResource(getResources(), R.mipmap.cute);
    //圆角Drawable
    imageView1.setImageDrawable(new RoundRectImageDrawable(b));
    //圆形Drawable
    imageView2.setImageDrawable(new CircleDrawable(b));
    • 1
    • 2
    • 3
    • 4
    • 5

    Shape

    Shape类型是用来绘制几何图形的,易用而且轻量化。一般使用XML来使用,放在res/drawable目录下。

    使用<shape>标签定义的是GradientDrawable

    Shape类是个抽象类,draw(Canvas canvas, Paint paint)必须实现,onResize(float width, float height)也是非常重要的方法。它有五种子类。

    子类说明
    RectShape 矩形、直角矩形、圆角矩形
    OvalShape 椭圆形、圆形
    PathShape 线形、环形
    Ring、Line 环形、环形进度条、线形、实线、虚线
    ArcShape 弧形

    Shape的通用属性:

    属性值说明
    shape 根标签。shape:[“rectangle”,”oval”,”ring”,”line”] ring有innerRadius[内环半径]、innerRadiusRatio、thickness[厚度]、thicknessRatio、useLevels等属性
    corners radius、topLeftRadius、topRightRadius…
    gradient 渐变色。startColor,centerColor、endColor、angle(由type决定,如果是linear类型,则表示从什么角度渐变)、type[“linear”、”radial”、”sweep”]…
    padding drawable中的属性。left、top、right、bottom
    size width、height,决定Shape的宽高,不设置则由view的宽高决定
    solid color 填充色。
    stroke 边角线:width、color、dashWidth(虚线宽度)、dashGap(虚线间隔)。

    例如:很容易做一个圆角的按钮背景图,不需要美工作图。

    <?xml version="1.0" encoding="utf-8"?>
    <!-- shape屬性設置形狀。 这里是矩形,也可以设置圆形(oval)-->
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <!-- 圆角半径 -->
        <corners android:radius="8dp" />
        <!-- 填充颜色 -->
        <solid android:color="#da87ef" />
        <!-- 大小-->
        <size
            android:width="100dp"
            android:height="100dp" />
        <!-- padding-->
        <padding
            android:bottom="8dp"
            android:left="8dp"
            android:right="8dp"
            android:top="8dp" />
        <!-- 边线。这里设置的虚线。shape="line"这个是必须的属性,也可以是唯一的属性。 -->
        <stroke
            android:width="1dp"
            android:color="@color/gray"
            android:dashGap="1dp"
            android:dashWidth="1dp" />
        <!-- gradient -->
        <!--<gradient
            android:centerColor="@color/green"
            android:endColor="@color/yellow"
            android:gradientRadius="50dp"
            android:startColor="@color/blue"
            android:type="radial" />-->
    </shape>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    效果如下: 
    Shape-Rectangel

    PathShape和ArcShape

    我们可以使用代码实现Path和Arc类型的drawable,绘制不同的几何形状。 
    PathShape-ArcShape

    ShapeDrawable shapeDrawable = null;
            Path p = new Path();
            p.moveTo(50,0);
            p.lineTo(0,50);
            p.lineTo(50,100);
            p.lineTo(100,50);
            p.lineTo(50,0);
            p.close();
            PathShape ps = new PathShape(p,100,100);
            shapeDrawable = new ShapeDrawable(ps);
            shapeDrawable.setBounds(0,0,100,150);
            shapeDrawable.getPaint().setStyle(Paint.Style.FILL);
            shapeDrawable.getPaint().setColor(Color.CYAN);
            imageViewShapePath.setBackgroundDrawable(shapeDrawable);
    
    
            //Arc shape
            ArcShape arcShape = new ArcShape(225,270);//初始180度,逆时针旋转270度。0度在右手水平位置。
            shapeDrawable = new ShapeDrawable(arcShape);
            shapeDrawable.setBounds(0,0,200,200);
            shapeDrawable.getPaint().setStyle(Paint.Style.FILL);
            shapeDrawable.getPaint().setColor(Color.BLUE);
            imageViewShapeArc.setBackgroundDrawable(shapeDrawable);
    
            arcShape = new ArcShape(45,270);//初始180度,旋转270度。0度在右手水平位置。
            shapeDrawable = new ShapeDrawable(arcShape);
            shapeDrawable.setBounds(0,0,200,200);
            shapeDrawable.getPaint().setStyle(Paint.Style.STROKE);
            shapeDrawable.getPaint().setColor(Color.RED);
            imageViewShapeRing.setBackgroundDrawable(shapeDrawable);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    ShapeDrawable和ShapeDrawable.ShaderFactory

    Shapedrawable直接在Java代码中使用。 
    Shape对象放入ShapeDrawable中,ShapeDrawables设置画笔样式。 
    Drawable尺寸变化时调用ShapeDrawable.ShaderFactory产生的Shader。 
    BitmapShaderComposeShaderLinearGradientRadialGradientSweepGradient

    //BitmapShader
    shapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() {
                @Override
                public Shader resize(int width, int height) {
                    return new BitmapShader(b, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
                }
            });
    
    //LinearGradient
    shapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() {
                @Override
                public Shader resize(int width, int height) {
                    return new LinearGradient(0,0,width,height,
                            new int[]{
                                    //可以设置多个颜色渐变,可以任意多个颜色
                                Color.RED,Color.BLACK,Color.BLUE
                            },null, Shader.TileMode.CLAMP);
                }
            });
            //SweepGradient   注意:最后两个参数的数量要一致
        shapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() {
                @Override
                public Shader resize(int width, int height) {
                    return new SweepGradient(width/2,height/2,
                            new int[]{
                                Color.RED,Color.YELLOW,Color.BLUE, Color.CYAN
                            },new float[]{0.1f,0.3f,0.7f,1.0f});
                }
            });    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    图片相关Drawable

    BitmapDrawable

    BitmapDrawable是对bitmap的一种封装。它可以设置绘制方式,使图片平铺、拉伸或保持图片原始大小。比如一些需要重复的图片,可以让美工提供很小的图片,我们使用BitmapDrawable来进行重复渲染。

    属性说明
    src 只能是图片,不能是xml定义的drawable
    gravity  
    antialias 是否开启抗锯齿
    dither 是否抖动
    filter 对图片进行滤波
    tileMode repeat、mirror、clamp(边缘拉伸)、disable
    tint 着色
    mipmap 是否可以用mipmap ,api>=17
    tileModeX api>=21
    tileModeY api>=21
    tintMode api>=21

    实现方法,有代码和xml方式:

    XML方式

    在res/drawable下定义bitmap drawable。

    <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:src="@mipmap/cute"
        android:tileMode="mirror"
        android:dither="true"
        android:antialias="true"/>
    • 1
    • 2
    • 3
    • 4
    • 5

    代码方式

    Bitmap b = BitmapFactory.decodeResource(getResources(),R.mipmap.cute);
    BitmapDrawable bd = new BitmapDrawable(getResources(),b);
    bd.setAntiAlias(true);
    bd.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
    ivBitmapPic.setImageDrawable(bd);
    • 1
    • 2
    • 3
    • 4
    • 5

    NinePatchDrawable

    .9图片最大的特点是在拉伸不会失帧。.9图片只能用于图片拉伸的情况。 
    也是可以res/drawable中使用<nine-patch>标签来定义一个NinePatchDrawable。不过都需要.9.png的图片。Android提供了.9图片的制作工具,在/tools目录下。

    PictureDrawable

    • Picture类。android.graphics.Picture。 
      不存储实际的像素,仅仅记录绘制的过程。
    • PictureDrawable(Picture p) 
      使用PictureDrawable,很多手机显示不出来。需要关闭对应的activity的硬件加速属性。android:hardwareAccelerated="false" 
      一般在代码中实现:
    Bitmap b = BitmapFactory.decodeResource(getResources(),R.mipmap.cute);
    Paint paint = new Paint();
    paint.setTextSize(30);
    Picture p = new Picture();
    Canvas c= p.beginRecording(b.getWidth(),b.getHeight());
    c.drawBitmap(b,0,0,paint);
    c.drawText("PictureDrawable",20,50,paint);
    p.endRecording();
    PictureDrawable drawable = new PictureDrawable(p);
    ivPicDrawable.setImageDrawable(drawable);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Color类型的Drawable

    ColorDrawable和ColorFilter

    ColorDrawable

    在Android工程的res目录下有两个地方可以设置ColorDrawable,分别是drawable和values目录,使用标签来设置color。 在drawable目录下设置color:

    <?xml version="1.0" encoding="utf-8"?>
    <color xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="#ff0000" />
    • 1
    • 2
    • 3

    在values目录下设置color:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="colorPrimary">#3F51B5</color>
        <color name="colorPrimaryDark">#303F9F</color>
        <color name="colorAccent">#FF4081</color>
        <drawable name="colorDrawable">#000000</drawable>
    </resources>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ColorFilter

    ColorFilter有3个子类。ImageView和ImageButton、Drawable以及Paint可以设置ColorFilter。

    子类ColorFilter说明
    ColorMatrixColorFilter 指定一个4*5的ColorFilter
    LightingColorFilter RGB颜色通道强度变换
    PorterDuffColorFilter RGB色混合效果,有18种混合效果

    - **ColorMatrix**![color-matrix](http://img.blog.csdn.net/20160420210249932)

    private void setArgb(int alpha,int red,int green,int blue){
            ColorMatrix colorMatrix = new ColorMatrix(new float[]{
                    red,0,0,0,0,
                    0,green,0,0,0,
                    0,0,blue,0,0,
                    0,0,0,alpha,0
            });
            drawable.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
            view.postInvalidate();
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • LightingColorFilter LightingColorFilter(int mul,int add)= (mul * 原色值 + add) % 255
    //表示过滤了blue的颜色,并增强55
    drawable.setColorFilter(new LightingColorFilter(0x0000ff,0x000055));
    • 1
    • 2
    • PorterDuffColorFilter PorterDuffColorFilter(int srcColor,PorterDuff.Mode mode)
    //mutate方法可以让同一个drawable在不同的控件上进行展示不同的效果。
    drawable.mutate().setColorFilter(new PorterDuffColorFilter(0x0000ff, PorterDuff.Mode.ADD));//18种效果。
    • 1
    • 2

    GradientDrawable和Tint

     GradientDrawable linearGradient = new GradientDrawable();
            linearGradient.setGradientType(GradientDrawable.LINEAR_GRADIENT);// RADIAL_GRADIENT,SWEEP_GRADIENT
            //xml中只有startColor、centerColor和endColor,在代码中可以设置任意多个color。
            linearGradient.setColors(new int[]{0xff0000, 0xff0001, 0x000ff1, 0xff2310, 0x12ff00});//API 16 above
            linearGradient.setShape(GradientDrawable.RECTANGLE);//OVAL,LINE,RING
            view.setBackground(linearGradient); // API 16 above
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Android5.0以后,引用了Tint的功能。 
    android:backgroundTint , android:tint及其对应的tintMode。ImageView有这两个属性,其它的只有backgound的tint。

    管理多个Drawable

    LayerDrawableLevelListDrawable 和 TransitionDrawable 它们之间有些相似性,都是管理多个 Drawable 的展示,其中 TransitionDrawable 是 LayerDrawable 的子类只管理2个 Drawable。不过,从类继承体系上分,LevelListDrawable 和 StateListDrawable 才是比较靠近的,效果也相似。

    StateListDrawable

    在res/drawable目录下可以定义根据View的状态(pressed,focus,checked等)的不同而显示不同drawable的drawable。这种drawable在开发中经常会用到,比如按钮点击显示按下去的背景。

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android"
        android:enterFadeDuration="300" android:exitFadeDuration="300">
        <item android:drawable="@drawable/shape_selected" android:state_selected="true"/>
        <item android:drawable="@drawable/shape_selected" android:state_pressed="true"/>
        <item android:drawable="@drawable/shape_normal" /><!-- 务必将无状态放在最后 -->
    </selector>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意:将正常状态的drawable放到最后,不然会看不到状态变化而导致的drawable变化。因为statelist drawbale是从上到下来搜索,如果有匹配的状态,则显示对应drawable。

    LayerDrawable

    LayerDrawable是一个多层的Drawable,可以对每一层的drawable进行控制。从而实现一些效果。它是这样在drawable目录下定义的:

    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@mipmap/mv" android:left="20dp" android:top="20dp" android:id="@+id/l1"/>
        <item android:drawable="@mipmap/mv" android:left="40dp" android:top="40dp" android:id="@+id/l2"/>
        <item android:left="60dp" android:top="60dp"  android:id="@+id/l3">
            <shape >
                <gradient android:centerColor="@color/blue"></gradient>
            </shape>
        </item>
    </layer-list>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    可以为每一层drawable设置id,这样可以控制每一层的drawable,从而达到一些特定的效果。比如下面是将最上层的drawable隐藏掉。 
    Layer-Drawable 
    通过Drawable d1 = custLayerDrawable.findDrawableByLayerId(R.id.l1);找到某个id对应的Drawable,然后可以进行操作,比如隐藏:d1.setAlpha(0); 
    当然,也可以通过代码来设置一个多层的drawable。例如:

    DisplayMetrics dm = getResources().getDisplayMetrics();
    Drawable [] ds = new Drawable[3];
    ds[0] = getResources().getDrawable(R.mipmap.mv);
    ds[1] = getResources().getDrawable(R.mipmap.mv);
    ds[2] = getResources().getDrawable(R.mipmap.mv);
    LayerDrawable layerDrawable = new LayerDrawable(ds);
    layerDrawable.setLayerInset(0,0,0,(int)(20 * dm.density),(int)(20 * dm.density));//第一个参数表示索引。
    layerDrawable.setLayerInset(1,0,0,(int)(40 * dm.density),(int)(40 * dm.density));
    layerDrawable.setLayerInset(2,0,0,(int)(60 * dm.density),(int)(60 * dm.density));
    imageViewLayer.setImageDrawable(layerDrawable);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    LevelListDrawable

    LevelListDrawable根据level-list中的每一个draawable的level范围来显示对应的drawable。比如在drawable目录中定义一个level-list:

    <!-- 的每一个level-child表示一种不同的颜色,只在一定的level值区间显示,方便演示。 -->
    <level-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/level_child" android:maxLevel="10" android:minLevel="0"/>
        <item android:drawable="@drawable/level_child1" android:maxLevel="20" android:minLevel="11"/>
        <item android:drawable="@drawable/level_child2" android:maxLevel="30" android:minLevel="21"/>
        <item android:drawable="@drawable/level_child3" android:maxLevel="40" android:minLevel="31"/>
        <item android:drawable="@drawable/level_child4" android:maxLevel="50" android:minLevel="41"/>
    </level-list>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    效果如图,当拖动seekbar改变drawable的level值时,进入到不同的level区间,则会显示不同的子drawable。 
    LevelList_drawable

    TransitionDraeable

    TransitionDraeable继承LayerDrawable,但它只能有2个子drawable。切换drawable会产生渐变动画,这时一个非常好的效果。同样,先定义drawable文件:

    <transition xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/level_child4" />
        <item android:drawable="@drawable/level_child5" />
    </transition>
    • 1
    • 2
    • 3
    • 4

    然后在代码中设置开始渐变,里面的参数表示动画的时间:两个方法,一个表示正向渐变,一个表示反向渐变。

      transitionDrawable.startTransition(500);
      transitionDrawable.reverseTransition(500);
    • 1
    • 2

    效果如下: 
    transitionDrawable

    容器类 Drawable

    ClipDrawableInsetDrawableRotateDrawableScaleDrawable 都是 DrawableWrapper 的子类。它们都是容器类 Drawable,自生只能有一个子 Drawable,通过对子 Drawable 进行处理来实现 clip、inset、rotate、scale 的效果

    ClipDrawable

    使用<clip>标签定义ClipDrawable,在res/drawable目录中。

    <!-- 水平方向裁剪、裁剪时从右到左、对gradient_progress进行裁剪-->
    <clip xmlns:android="http://schemas.android.com/apk/res/android"
        android:clipOrientation="horizontal"
        android:gravity="left"
        android:drawable="@drawable/gradient_progress_h">
    </clip>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    <!-- 图片四周扩散和四周聚拢-->
    <clip xmlns:android="http://schemas.android.com/apk/res/android"
        android:clipOrientation="horizontal|vertical"
        android:gravity="center"
        android:drawable="@mipmap/mv">
    </clip>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过在代码中设置Drawable的Level来控制裁剪效果。容器类Drawable都是通过setLevel(int level)来控制的,level值的范围是[0,10000]。

    imageView.getDrawable().setLevel(10000);
    • 1

    效果图: 
    Clip-Drawable

    InsetDrawable

    InsetDrawable主要是为设置backgroud背景的控件的drawable设置边距,类似padding。设置方式也是在res/drawable目录下,使用<inset>标签,里面放一个drawable,然后设置四个边距。

    <inset xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/inset_shape"
        android:insetBottom="20dp"
        android:insetLeft="20dp"
        android:insetRight="20dp"
        android:insetTop="20dp">
    </inset>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    RotateDrawable

    RotateDrawable很容易实现旋转的效果。比如指针转盘。同样是在res/drawable目录下,使用<rotate>标签来设定一个RotateDrawabl。

    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@mipmap/mv"
        android:fromDegrees="0"
        android:toDegrees="180"
        android:pivotX="50%"<!-- %p表示在父控件中的百分比 -->
        android:pivotY="50%"<!-- %p表示在父控件中的百分比 -->
        android:visible="true">
    </rotate>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    上面定义了一个图片,从0°-180°,以自己的中心点为中心旋转180。 
    Rotate-Drawable

    ScaleDrawable

    ScaleDrawable很容易实现缩放的效果。设置方式和上面的drawable一样。如:

    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@mipmap/mv"
        android:useIntrinsicSizeAsMinimum="false"
        android:scaleWidth="50%"<!-- 宽度缩放比例 -->
        android:scaleHeight="50%"<!-- 高度缩放比例 -->
        android:scaleGravity="right|top"><!-- 缩放后的位置 -->
    </scale>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Scale-Drawable

    矢量图VectorDrawable

    在 Android5.0(API Level 21)中引入了 VectorDrawable 和 AnimatedVectorDrawable,矢量图不会因为图像放大而失真,而且占用内存小。所以学会矢量图并用好它,将对开发 APP 非常有用。VectorDrawable只支持部分的SVG规范。一般去找成型的SVG图片。

    VectorDrawable

    矢量图中保存的只是图像绘制的方法: 
    大写代表后面的参数是绝对坐标,小写代表相对坐标。

    方法说明
    M moveTo绘制点。
    L lineTo画直线
    Z close开始点-结束点闭合
    C cubic bezier三次贝塞尔曲线
    Q quatratic bezier二次贝塞尔曲线
    A 圆弧rx ry x-rotation large-arc-flag sweep-flag xy

    vector

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="60dp"
        android:height="60dp"
        android:viewportHeight="600"
        android:viewportWidth="600">
        <group
            android:name="group"
            android:pivotX="300.0"
            android:pivotY="300.0"
            android:rotation="0.0">
            <path
                android:name="v"
                android:fillColor="@android:color/black"
                android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /><!-- M到300,70,然后l到0,-70 -->
        </group>
    </vector>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    AnimatedVector

    属于属性动画。

    此篇文章是学习极客学院hexter老师的做的笔记。

  • 相关阅读:
    SharePoint 2010 编程链接两个web part
    SharePoint 2010 Value does not fall within the expected range
    SharePoint 自定义开发chart web part
    跨站点显示SharePoint 列表或者文档库 cross site
    SharePoint Javascript 改变当前站点语言
    【转】 C++11中值得关注的几大变化
    XPM
    Thinking in C++ 第一章 对象导言
    Thinking in C++ 第4,5,6,7章
    Internal DSL
  • 原文地址:https://www.cnblogs.com/dongweiq/p/6054950.html
Copyright © 2011-2022 走看看