多样化的Drawable

原来不知道Drawable有这么多东西现在才学到0.0

Drawable有很多种,他们都表示一种图像的概念,通过颜色也可以构造出各式各样的图像效果。Drawable常被用来作为Viewde的背景使用,Drawble一般通过XML来定义,当然我们也可以通过代码创建具体的Drawable对象,知识代码创建会麻烦。Drawble是一个抽象类,它是所有Drawable对象的基类,每个具体的Drawable都是是它的子类,比如ShapDrawable、BitmapDrawable等,具体的看Drawable层次请自行查看。


Drawable的内部宽/高这个参数比较重要,通过getIntrinsicWidth和getIntrinsicHeight这两个方法可以获取到他们。但不是所有的Drawable都有内部宽/高,比如一种图片所形成的Drawable,它的内部宽/高就是图片的宽高,但是一个颜色所形成的Drawable,他就没有内部的宽高的概念。另外注意的是,Drawable的内部宽高不等同于它的大小,一般来说Drawable是没有大小概念的,当作用View的背景时,Drawable会被拉伸至View的同等大小。

Drawable的种类繁多,常见的 BitmapDrawable、ShapeDrawable、LayerDrawable以及StateListDrawable



1、BitmapDrawable
它表示一张图片,在实际开发中直接引用图片即可
通过xml设置

<bitmap
    xmlns: android = "http://schemas.android.com/apk/res/android"
    android :src= "@mipmap/ic_launcher"
    android :antialias= "true"
    android :dither= "true"
    android :gravity= "center"
    android :filter= "true"
    android :mipMap= "true"
    android :tileMode= "repeat"
    />




android :src 图片的资源ID
android :antialias图片抗锯齿功能
android :dither 抖动效果
android :filter 开启过滤效果
android :gravity  图片定位
android :mipMap 这是一种图像相关的处理技术,也叫纹理映射,比较抽象,这里也不对其深究了,默认值为false,在日常开发中此项不常用
android :tileMode 平铺模式 (4个选择:关闭平铺模式 disable   平铺模式 : repeat 表示的是简单的水平和竖直方向上的效果,mirror表示在水平和竖直方向的镜面投影效果,repeat表示的简单的水平和竖直方向上的平铺效果)


2、ShapeDrawable
通过颜色来构造的图像 它既可以是纯色的图形,也可以是具有渐变的图形。ShapeDrawable的语法稍微复杂点


<? xml version= "1.0"  encoding= "utf-8" ?>
<shape  xmlns: android = "http://schemas.android.com/apk/res/android"
    android :shape= "rectangle" >
    <corners
        android :bottomLeftRadius= "50dp"
        android :bottomRightRadius= "50dp"
        android :radius= "30dp"
        android :topLeftRadius= "10dp"
        android :topRightRadius= "10dp"  />
    <gradient
        android :angle= "10dp"
        android :centerColor= "@color/colorAccent"
        android :centerX= "20dp"
        android :centerY= "20dp"
        android :endColor= "@color/colorAccent"
        android :gradientRadius= "50dp"
        android :startColor= "@color/colorAccent"
        android :type= "radial"
        android :useLevel= "true"  />
    <padding
        android :bottom= "10dp"
        android :left= "10dp"
        android :right= "10dp"
        android :top= "10dp"  />
    <size
        android :width= "110dp"
        android :height= "110dp"  />
    <solid  android :color= "@color/colorPrimaryDark"  />
    <stroke
        android :width= "10dp"
        android :color= "@color/colorAccent"
        android :dashGap= "10dp"
        android :dashWidth= "10dp"  />
</shape>


android:shape表示图形的形状,有四个选型:rectangle(矩形)、oval(椭圆)、line(横线)和ring(圆环)

它的默认值是矩形,另外line和ring这两个选项必须要通过<stroke>标签来指定线的宽度和颜色等消息,否则将无法达到预期的效果
针对ring这个形状,有5个特殊的属性:
android:innerRadius 圆环的内直径,和android:innerRadiusRatio同时存在,以android:innerRadius为准
android:thickness 圆的厚度,及外半径减去内半径的大小,和android:thiscknessRatio同时存在时,以android:thickness为准
android:innerRadiusRatio:内半径占整个Drawable宽度的比例,默认值为9,如果为n,那么内半径 = 宽度/n
android:thicknessRatio:厚度占整个Drawable宽度的比例,默认值为3。如果为n,那么厚度 = 宽度 / n
android:useLevel:一般都应该使用false,否则有可能无法达到预期的显示效果,除非它被当做LevelListDrawable来使用

<corners>
表示shape的四个角的角度。它只适合用于矩形shape,这里的角度是指圆角的程度 ,用px来表示,它的5个属性:
—android:radius  为4个角度同事设定相同的角度,优先级较低,会被其他四个属性覆盖
—android:topLeftRadius  设定最上角的角度
—android:topRightRadius 设定右上角的角度
—android:bottomLeftRadius  设定最下角的角度
—android:bottomRightRadius  设定右下角的角度

<gradient>
它与<solid>标签是互相排斥的,其中solid表示纯色填充,而gradiect则表示渐变效果,gradient有如下属性:
—android:angle   渐变的角度,默认为0,其值必须为45的倍数,0表示从左到右,90表示从下到上,具体的效果需要自己去调试,总之角度会影响渐变的方向
—android:centerX   渐变的中心点横坐标
—android:centerY   渐变的中心点的纵坐标
—android:startColor    渐变的起始颜色
—android:centerColor  渐变的中间颜色
—android:endColor   渐变的结束颜色
—android:gradientRadius   渐变的半径,仅当android:type: = “radial”时有效
—android:userLevel   一般为false,当Drawable作为StateListDrawable使用时为true;
—android:type   渐变的类别 有linear(线) 、 radial(径向渐变)、sweep(扫描线渐变)默认为线性渐变

<panding>
这个表示空白,但是它的表示表示shape的空白,而是包含它的View的空白,有4个属性:android:left 、android:top、android:right、android:bottom

<solid>表示纯色填充,通过android:color即可指定shape中填充的颜色

<stroke>Shape的描边
—android:width     描边的宽度,越大则shape的边缘线就会看起来越粗
—android:color      描边的颜色
—android:dashWidth     组成虚线的线段的宽度
—android:dashGap      组成虚线线段之间的间隔,间隔越大则虚线看起来空隙就越大。

<size>
shape的大小


3、LayerDrawable 
LayerDrawable对应得XML标签是<layer-list>,表示一种层次化的Drawable集合

<? xml version= "1.0"  encoding= "utf-8" ?>
<layer-list  xmlns: android = "http://schemas.android.com/apk/res/android" >
    <item
        android :drawable= "@drawable/shape_rect_stroke_drawable"
        android :bottom= "10dp"
        android :top= "10dp"
        android :right= "10dp"
        android :left= "10dp"
        android :id= "@+id/textView4"
        >
    </item>
   
    <item>
    </item>
    ........
</layer-list>

一个layer-list中可以包括多个item,每个item表示一个Drawable。我们可以通过android:drawable属性来直接引用一个已有的Drawable资源,也可以在item中自定义Drawable。layer-list中的所有的Drawable都会被缩放至View的大小,对于bitmap来说,需要使用android:gravity属性才能控制图片的显示效果。
例子:
<? xml version= "1.0"  encoding= "utf-8" ?>
<layer-list  xmlns: android = "http://schemas.android.com/apk/res/android" >
    <item>
        <shape>
            <solid  android :color= "#0ac39e"  />
        </shape>
    </item>

    <item  android :bottom= "6dp" >
        <shape>
            <solid  android :color= "#ffffff"  />
        </shape>
    </item>

    <item
        android :bottom= "1dp"
        android :left= "1dp"
        android :right= "1dp" >
        <shape  android :shape= "rectangle" >
            <solid  android :color= "#ffffff"  />
        </shape>
    </item>
</layer-list>


4、StateListDrawable (重点)
StateListDrawable对应于<selector>标签,它也是表示Drawable集合,每一个Drawable对应着View的一种状态,StateListDrawable主要用于设置可单击的View的背景,最常见的是Button。

<? xml version= "1.0"  encoding= "utf-8" ?>
<selector  xmlns: android = "http://schemas.android.com/apk/res/android"
    android :constantSize= "true"
    android :dither= "true"
    android :variablePadding= "true" >
    <item
        android :drawable= "@drawable/state_list_all_values_drawable"
        android :state_pressed= "true"
        android :state_focused= "true"
        android :state_hovered= "true"
        android :state_selected= "true"
        android :state_checked= "true"
        android :state_checkable= "true"
        android :state_enabled= "true"
        android :state_activated= "true"
        android :state_window_focused= "true"
        />
</selector>

android:constantSize    的固有大小是否不随着其状态的改变和改变的,因为状态的改变会导致StateListDrawable切换到具体的Drawable,而不同的Drawable具有不同的固有大小。True表示StateListDrawable的固有大小保持不变,这是他的固有大小是内部所有Drawable的固有大小的最大值,false则会随着状态的改变而改变。此选项默认值为false。

android:dither   是否开启抖动效果,开启此选项可以让图片在低质量的屏幕上仍然获得较好的显示效果,默认值为True

android:variablePadding    StateListDrawable的padding表示是否随着其状态的改变而改变,true表示会随着状态的改变而改变,false表示StateListDrawable的padding是内部所有Drawable的padding的最大值,此选项默认为false,并且不建议开启此选项。

<item>标签表示一个具体的Drawable

—android:state_pressed 表示按下状态,比如button被按下后仍没有松开时的状态
—android:state_focused 表示View已经获取了焦点
—android:state_selected 表示用户选择了View
—android:state_checked 表示用户选中了View,一般适用于checkBox这类在选中和非选中状态之间进行切换的View
—android:state_enabled 表示view处于可用状态

5、LevelListDrawable

LevelListDrawable对应于<level-list>标签,它同样表示一个Drawable集合,集合中的每一个Drawable都有一个等级的概念。根据不同的等级,LevelListDrawable会切换对应的Drawable

<? xml version= "1.0"  encoding= "utf-8" ?>
<level-list  xmlns: android = "http://schemas.android.com/apk/res/android" >
    <item
        android :drawable= "@drawable/focused_drawable"
        android :maxLevel= "10"
        android :minLevel= "10"
        />
</level-list>

每个Item表示一个Drawable,并且有对应的等级范围由android:minLevel和android:mxLevel来指定。

6、TransitionDrawable
TransitionDrawable对应于<transition> 标签,它用于实现两个Drawable之间的淡入浅出效果

<? xml version= "1.0"  encoding= "utf-8" ?>
<transition  xmlns: android = "http://schemas.android.com/apk/res/android" >
    <item  android :drawable= "@drawable/focused_drawable"  />
    <item  android :drawable= "@drawable/pressed_drawable"  />
</transition>


7、InsetDrawable
InsetDrawable对应于<inset>标签,它可以将其他Drawable内嵌到自己当中,并可以在四周留有一定的间距。

<? xml version= "1.0"  encoding= "utf-8" ?>
<inset  xmlns: android = "http://schemas.android.com/apk/res/android"
    android :drawable= "@drawable/focused_drawable"
    android :insetBottom= "15dp"
    android :insetLeft= "15dp"
    android :insetRight= "15dp"
    android :insetTop= "15dp" >

    <shape  android :shape= "rectangle" >
        <solid  android :color= "#ff0000"  />
    </shape>

</inset>

8、ScaleDrawable
ScaleDrawable对应于<scale>标签,它可以根据自己等级将指定Drawable缩放到一定比例

<? xml version= "1.0"  encoding= "utf-8" ?>
<scale  xmlns: android = "http://schemas.android.com/apk/res/android"
    android :drawable= "@drawable/image_one"
    android :scaleWidth= "70%"
    android :scaleHeight= "70%"
    android :scaleGravity= "center"
    />

这里记住要想ScaleDrawable可见,那么它的等级就不能为0看源码

@Override
public void  draw(Canvas canvas) {
    final Drawable d = getDrawable() ;
    if (d !=  null && d.getLevel() !=  0) {
        d.draw(canvas) ;
    }
}


那么它的等级就得设置大于0的数且小于等于10000

//scale
scaleTV = (TextView) findViewById(R.id. scale_tv) ;
ScaleDrawable scaleDrawable = (ScaleDrawable)  scaleTV.getBackground() ;
scaleDrawable.setLevel( 1) ;
scaleDrawable.setLevel( 1) ;这里一定要记住


9、ClipDrawable
ClipDrawable对应<clip>标签,它可以根据自己当前等级来裁剪另一个Drawable,裁剪方向可以通过android:clipOrientation和android:gravity这两个属性来共同控制

<? xml version= "1.0"  encoding= "utf-8" ?>
<clip  xmlns: android = "http://schemas.android.com/apk/res/android"
    android :clipOrientation= "vertical"
    android :drawable= "@drawable/image_one"
    android :gravity= "bottom" >
</clip>

代码设置
//clipe
clipeIMG = (ImageView) findViewById(R.id. clipe_img) ;
ClipDrawable clipDrawable = (ClipDrawable)  clipeIMG.getDrawable() ;
clipDrawable.setLevel( 3000) ;

这里需要主要的是ClipeDrawable也是有等级,它的范围是0~~10000 值越大裁剪区域越小  反之越大


10、自定义的Drawable
package com.example.jiangtao.aima.view ;

import android.graphics.Canvas ;
import android.graphics.ColorFilter ;
import android.graphics.Paint ;
import android.graphics.PixelFormat ;
import android.graphics.Rect ;
import android.graphics.drawable.Drawable ;

/**
 * Created by jiangtao
 * 16/5/20
 * com.example.jiangtao.aima.view
 * Aima
 */
public class MyDrawable  extends Drawable {

    private Paint  mPaint ;

    public MyDrawable( int color) {
        mPaint new Paint(Paint. ANTI_ALIAS_FLAG) ;
        mPaint.setColor(color) ;
    }

    @Override
    public void  draw(Canvas canvas) {
        final Rect rect = getBounds() ;
        float cx = rect.exactCenterX() ;
        float cy = rect.exactCenterY() ;

    }

    @Override
    public void  setAlpha( int alpha) {
        mPaint.setAlpha(alpha) ;
    }

    @Override
    public void  setColorFilter(ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter) ;
        invalidateSelf() ;
    }

    @Override
    public int  getOpacity() {
        return PixelFormat. TRANSLUCENT ;
    }
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值