Android中常用的Drawable

q3202dasz 8年前
   <h2><strong>前言</strong></h2>    <p> </p>    <ul>     <li> <p>本文的目录结构</p>      <ul>       <li>前言</li>       <li>Drawable简介</li>       <li>Drawable分类        <ul>         <li>BitmapDrawable</li>         <li>NinePatchDrawable</li>         <li>ShapeDrawable</li>         <li>LayerDrawable</li>         <li>StateListDrawable</li>         <li>LevelListDrawable</li>         <li>TransitionDrawable</li>         <li>InsetDrawable</li>         <li>ScaleDrawable</li>         <li>ClipDrawable</li>        </ul> </li>       <li>自定义Drawable</li>      </ul> </li>    </ul>    <h2><strong>Drawable简介</strong></h2>    <ul>     <li> <p>Drawable表示的是一种可以在Canvas上进行绘制的抽象的概,可以是纯颜色,也可以是图片等。</p> </li>     <li> <p>Drawable一般是通过XML来定义,当然也可以通过代码来创建。</p> </li>     <li> <p>Drawable类是抽象类,它是所有Drawable的基类。</p> </li>     <li> <p>Drawable的 getIntrinsicWidth() 和 getIntrinsicHeight() 获取其内部宽/高。并不是所有Drawable都有内部宽/高。图片所形成的Drawable的内部宽/高就是图片的宽/高。颜色所形成的Drawable就没有内部宽/高的概念了。</p> </li>     <li> <p>Drawable是没有大小概念的,当用作View的背景时,会被拉伸至View的同等大小。</p> </li>     <li> <p>Drawable的使用范围很单一:一是作为ImageView中的图像显示,二是作为View的背景。</p> </li>    </ul>    <h2><strong>Drawable分类</strong></h2>    <h2><strong>BitmapDrawable</strong></h2>    <ul>     <li> <p>对应 <bitmap> 标签,几乎是最简单的Drawable,表示一张图片。</p> </li>     <li> <p>在实际开发中,我们可直接引用原始的图片,也可通过XML的方式来描述它。</p> </li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <bitmap      xmlns:android="http://schemas.android.com/apk/res/android"      android:src="@[package:]drawable/drawable_resource"      android:antialias="[true | false]"      android:dither="[true | false]"      android:filter="[true | false]"      android:gravity="[top | bottom | left | right |       center_vertical | fill_vertical | center_horizontal |        fill_horizontal | center | fill |         clip_vertical | clip_horizontal]"      android:mipMap="[true | false]"      android:tileMode="[disabled | clamp | repeat | mirror]" /></code></pre>    <ul>     <li> <p>android:src :图片的资源id。</p> </li>     <li> <p>android:antialias :是否开启图片抗锯齿。开启后会让图片变得平滑,同时也会一定程度上降低图片的清晰度。</p> </li>     <li> <p>android:dither :是否开启抖动效果。开启后可让高质量的图片在低质量的屏幕上能保持较好的显示效果。</p> </li>     <li> <p>android:filter :是否开启过滤效果。当图片尺寸被拉伸或压缩时,开启过滤效果可保持较好的显示效果。</p> </li>     <li> <p>android:gravity :当图片小于容器的尺寸时,设置此属性对图片进行定位。此属性的可选项较多,也可用 | 来组合使用。</p> </li>    </ul>    <table>     <thead>      <tr>       <th>可选项</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>top</td>       <td>将图片放在容器的顶部,不改变其大小。</td>      </tr>      <tr>       <td>bottom</td>       <td>将图片放在容器的底部,不改变其大小。</td>      </tr>      <tr>       <td>left</td>       <td>将图片放在容器的左部,不改变其大小。</td>      </tr>      <tr>       <td>right</td>       <td>将图片放在容器的右部,不改变其大小。</td>      </tr>      <tr>       <td>center_vertical</td>       <td>使图片竖直居中,不改变其大小。</td>      </tr>      <tr>       <td>center_horizontal</td>       <td>使图片水平居中,不改变其大小。</td>      </tr>      <tr>       <td>fill_vertical</td>       <td>图片竖直方向填充容器</td>      </tr>      <tr>       <td>fill_horizontal</td>       <td>图片水平方向填充容器</td>      </tr>      <tr>       <td>center</td>       <td>使图片居中,不改变其大小。</td>      </tr>      <tr>       <td>fill</td>       <td>图片填充容器,默认值。</td>      </tr>      <tr>       <td>clip_vertical</td>       <td>竖直方向的裁剪。</td>      </tr>      <tr>       <td>clip_horizontal</td>       <td>水平方向的裁剪。</td>      </tr>     </tbody>    </table>    <ul>     <li> <p>android:mipMap :是否开启纹理映射。</p> </li>     <li> <p>android:tileMode :平铺模式。</p> </li>    </ul>    <table>     <thead>      <tr>       <th>可选项</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>disabled</td>       <td>默认值,关闭平铺模式。</td>      </tr>      <tr>       <td>clamp</td>       <td>图片四周的像素会扩展到周围区域。</td>      </tr>      <tr>       <td>repeat</td>       <td>简单的水平和竖直方向上的平铺效果。</td>      </tr>      <tr>       <td>mirror</td>       <td>在水平和竖直方向上的镜面投影效果。</td>      </tr>     </tbody>    </table>    <h2><strong>NinePatchDrawable</strong></h2>    <ul>     <li> <p>表示一张 .9 格式的图片。 .9 图片可自动地根据所需的宽/高进行相应的缩放并保证不失真。</p> </li>     <li> <p>在实际使用中直接引用 .9 图片,也可以通过XML来描述它。</p> </li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <nine-patch      xmlns:android="http://schemas.android.com/apk/res/android"      android:src="@[package:]drawable/drawable_resource"      android:dither="[true | false]" /></code></pre>    <ul>     <li> <p>android:src :图片的资源id。</p> </li>     <li> <p>android:dither :是否开启抖动效果。开启后可让高质量的图片在低质量的屏幕上能保持较好的显示效果。</p> </li>    </ul>    <h2><strong>ShapeDrawable</strong></h2>    <ul>     <li>图形。可是纯色的图形,也可以是具有渐变效果的图形。</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <shape      xmlns:android="http://schemas.android.com/apk/res/android"      android:shape="[rectangle | oval | line | ring]"      <corners          android:radius="integer"          android:topLeftRaidus="integer"          android:topRightRaidus="integer"          android:bottomLeftRaidus="integer"          android:bottomRightRaidus="integer" />      <gradient          android:angle="integer"          android:centerX="integer"          android:centerY="integer"          android:centerColor="color"          android:endColor="color"          android:gradientRadius="integer"          android:startColor="color"          android:type="[linear | radial | sweep]"          android:useLevel="[true | false]" />      <padding          android:left="integer"          android:top="integer"          android:right="integer"          android:bottom="integer" />      <size          android:width="integer"          android:height="integer" />      <solid          android:color="color" />      <stroke          android:width="integer"          android:color="color"          android:dashWidth="integer"          android:dashGap="integer" /></code></pre>    <ul>     <li> <p>android:shape :图形的形状,可选有 <strong>rectangle(矩形)、oval(椭圆)、line(横线)和ring(圆环)</strong> 。默认是rectangle。注意line和ring必须通过 <stroke> 标签来指定线的宽度和颜色等信息,否则无法达到预期的显示效果。</p> </li>     <li> <p>android:shape="ring" 有5个特殊属性。</p> </li>    </ul>    <table>     <thead>      <tr>       <th>属性</th>       <th>描述</th>      </tr>     </thead>     <tbody>      <tr>       <td>android:innerRadius</td>       <td>圆环的内半径。<Br>会覆盖android:innerRadiusRatio。</td>      </tr>      <tr>       <td>android:innerRadiusRatio</td>       <td>内半径占整个Drawable宽度的比例。<br> 默认为9,若为n,则内半径 = 宽度 / n。</td>      </tr>      <tr>       <td>android:thickness</td>       <td>圆环的厚度。即外半径减去内半径的大小。<Br>会覆盖android:thicknessRatio</td>      </tr>      <tr>       <td>android:thicknessRatio</td>       <td>厚度占整个Drawable宽度的比例。<br> 默认为3,若为n,则厚度 = 宽度 / n。</td>      </tr>      <tr>       <td>android:useLevel</td>       <td>常为false,除非它被当做是LevelListDrawable。</td>      </tr>     </tbody>    </table>    <ul>     <li> <p><corners> :表示shape的四个圆角的角度,只适用于矩形。</p>      <ol>       <li>android:radius :为四个角同事设定相同的角度。优先级比以下4个属性要低。</li>       <li>android:topLeftRadius :左上角的角度。</li>       <li>android:topRightRadius :右上角的角度。</li>       <li>android:bottomLeftRadius :左下角的角度。</li>       <li>android:bottomRightRadius :右下角的角度。</li>      </ol> </li>     <li> <p><solid> :纯色填充,通过 android:color 指定填充的颜色。</p> </li>     <li> <p><gradient> :渐变效果。与 <solid> 纯色填充是互相排斥的。</p>      <ol>       <li>android:angle :渐变的角度。默认为0,其值必须为45的倍数。此角度会影响渐变的方向,0表示从左到右,90表示从下到上。</li>       <li>android:centerX :渐变的中心点的X坐标。</li>       <li>android:centerY :渐变的中心点的Y坐标。</li>       <li>android:startColor :渐变的起始色。</li>       <li>android:centerColor :渐变的中间色。</li>       <li>android:endColor :渐变的结束色。</li>       <li>android:gradient :渐变半径。仅当 android:type="radial" 时有效。</li>       <li>android:useLevel :一般为false,当Drawable作为StateListDrawable时为true。</li>       <li>android:type :渐变的类别。有linear(线性渐变)、radial(径向渐变)、sweep(扫描线渐变),默认为linear。</li>      </ol> </li>     <li> <p><stroke> :描边。</p>      <ol>       <li>android:width :描边的宽度。</li>       <li>android:color :描边的颜色。</li>       <li>android:dashWidth :虚线的宽度。</li>       <li>android:dashGap :虚线之间的间隔。</li>      </ol> </li>     <li> <p><padding> :空白。有 top 等四个属性。</p> </li>     <li> <p><size> :大小。其 android:width 和 android:height 分别设定shape的宽/高。注意,这个表示的是shape的固有大小,但并不是其最终大小。</p> </li>    </ul>    <h2><strong>LayerDrawable</strong></h2>    <ul>     <li>对应 <layer-list> 标签,表示一种层次化的Drawable集合,通过将不同的Drawable放置在不同的层上面从而达到一种叠加后的效果。</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <layer-list      xmlns:android="http://schemas.android.com/apk/res/android"      <item          android:drawable="@[package:]drawable/drawable_resource"          android:id="@[+][package:]id/resource_name"          android:top="dimension"          android:right="dimension"          android:bottom="dimension"          android:left="dimension" />      <!-- 其他item -->  </layer-list></code></pre>    <ul>     <li> <p>一个layer-list可包含多个item,每个item表示一个Drawable。可在 android:drawable 中引用一个现有的Drawable资源,也可在 <item> 中自定义Drawable。</p> </li>     <li> <p>默认情况下,layer-list中的所有Drawable都会被缩放至View的大小。可设置Drawable相对于View的上下左右偏移量。另外对于bitmap,需要使用其 android:gravity 来控制图片的显示效果。</p> </li>     <li> <p>layer-list有层次的概念, <strong>下面的item会覆盖上面的item</strong> 。通过合理的分层,可实现一些特殊的叠加效果。</p> </li>     <li> <p>利用layer-list实现一个文本输入框。</p> <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">        <item>            <shape android:shape="rectangle">                <solid android:color="#0ac39e" />            </shape>        </item>        <item android:bottom="6dp">            <shape android:shape="rectangle">                <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></code></pre> <img src="https://simg.open-open.com/show/4ef180904917f5f1229108d561a1c970.jpg"> <p>layer-list背景的输入框</p> </li>    </ul>    <h2><strong>StateListDrawable</strong></h2>    <ul>     <li>对应 <selector> 标签,表示一个Drawable的集合。 <strong>每个Drawable对应着View的一种状态</strong> ,系统会根据View的状态来选择合适的Drawable。</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <selector xmlns:android="http://schemas.android.com/apk/res/android"      android:constantSize="[true | false]"      android:dither="[true | false]"      android:variablePadding="[true | false]">      <item          android:drawable="@[package:]drawable/drawable_resource"          android:state_pressed="[true | false]"          android:state_focused="[true | false]"          android:state_hovered="[true | false]"          android:state_selected="[true | false]"          android:state_checkable="[true | false]"          android:state_checked="[true | false]"          android:state_enabled="[true | false]"          android:state_activated="[true | false]"          android:state_window_focused="[true | false]" />      <!-- 其他item -->  </selector></code></pre>    <ul>     <li> <p>android:constantSize :StateListDrawable的固有大小是否不随着其状态的改变而改变。默认为false,即随着状态的改变而改变大小。若为true,则表示其内部所有Drawable的固有大小的最大值。</p> </li>     <li> <p>android:dither :是否开启抖动效果。</p> </li>     <li> <p>android:variblePadding :StateListDrawable的padding是否随着其状态的改变而改变。默认为false,表示其内部所有Drawable的padding的最大值。若为true,表示会随着状态的改变而改变。</p> </li>     <li> <p><item> :表示某种状态下的一个具体的Drawable。用 android:drawable 指定一个现有Drawable的资源id,剩下的属性表示的是View的各种状态。</p> </li>    </ul>    <table>     <thead>      <tr>       <th>状态</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>android:state_pressed</td>       <td>表示按下状态。</td>      </tr>      <tr>       <td>android:state_focused</td>       <td>表示已经获取了焦点。</td>      </tr>      <tr>       <td>android:state_selected</td>       <td>表示用户选择了View。</td>      </tr>      <tr>       <td>android:state_checked</td>       <td>表示用户选中了View。<Br>适用于CheckBox这类在选中和非选中状态之间进行切换的View。</td>      </tr>      <tr>       <td>android:state_enabled</td>       <td>表示View当前处于可用状态。</td>      </tr>     </tbody>    </table>    <ul>     <li>系统会按照从上到下的顺序查找,直至查找到第一条匹配的item。一般来说,默认的item都应该放在selector的最后一条,并且不附带任何的状态。</li>    </ul>    <h2><strong>LevelListDrawable</strong></h2>    <ul>     <li>对应 <level-list> 标签,表示一个Drawable集合,集合中的每个Drawable都有一个等级的概念。根据不同的等级,LevelListDrawable会切换为对应的Drawable。</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <level-list xmlns:android="http://schemas.android.com/apk/res/android">      <item          android:drawable="@[package:]drawable/drawable_resource"          android:maxLevel="integer"          android:minLevel="integer" />      <!-- 其他item -->  </level-list></code></pre>    <ul>     <li> <p>每个item表示一个Drawable,并且有对应的等级范围,在 maxLevel 和 minLevel 之间。取值范围为0~10000,默认为0。</p> </li>     <li> <p>若作为View背景时,可通过Drawable的 setLevel() 来设置不同的等级来切换具体的Drawable。若作为ImageView的前景,可通过ImageView的 setImageLevel() 来切换。</p> </li>    </ul>    <h2><strong>TransitionDrawable</strong></h2>    <ul>     <li>对应于 <transition> 标签,用于实现两个Drawable之间的淡入淡出效果。</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <transition xmlns:android="http://schemas.android.com/apk/res/android">      <item          android:drawable="@[package:]drawable/drawable_resource"          android:id="@[+][package:]id/resource_name"          android:top="dimension"          android:right="dimension"          android:bottom="dimension"          android:left="dimension" />      <!-- 另一个item,注意transition只包含两个item -->  </transition></code></pre>    <ul>     <li>常将TransitionDrawable作为View的背景,再调用它的 startTransition() 和 reverseTransition() 来实现淡入淡出效果以及它的逆过程。</li>    </ul>    <pre>  <code class="language-java">ImageView ivBg = (ImageView) findViewById(R.id.iv_bg);  TransitionDrawable drawable = (TransitionDrawable) ivBg.getBackground();  drawable.startTransition(1000);</code></pre>    <h2><strong>InsetDrawable</strong></h2>    <ul>     <li>对应 <inset> 标签,可将其他Drawable内嵌到自己当中,并可在四周留出一定的间距。</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <inset       xmlns:android="http://schemas.android.com/apk/res/android"      android:drawable="@[package:]drawable/drawable_resource"      android:inset="dimension"      android:insetTop="dimension"      android:insetRight="dimension"      android:insetBottom="dimension"      android:insetLeft="dimension" /></code></pre>    <ul>     <li>当一个View希望自己的背景比自己的实际区域小的时候,可采用InsetDrawable,并通过 inset* 属性来设置留白。</li>    </ul>    <h2><strong>ScaleDrawable</strong></h2>    <ul>     <li>对应 <scale> 标签,将Drawable缩放到一定比例。</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <scale       xmlns:android="http://schemas.android.com/apk/res/android"      android:drawable="@[package:]drawable/drawable_resource"      android:scaleGravity="[top | bottom | left | right |          center_vertical | center_horizontal | center |          fill_vertical | fill_horizontal | fill |          clip_vertical | clip_horizontal]"      android:scaleWidth="percentage"      android:scaleHeight="percentage" /></code></pre>    <ul>     <li> <p>android:scaleGravity :等同于BitmapDrawable的 android:gravity 。</p> </li>     <li> <p>android:scaleWidth 和 android:scaleHeight :指定Drawable宽/高的缩放比例,以百分比的形式表示。如 70% ,表示缩放到原来的30%。</p> </li>    </ul>    <ul>     <li>从ScaleDrawable的 draw() 源代码来看,若等级为0时,不可见。等级默认为0,所以调用ScaleDrawable的 setLevel() 设置一个大于0的等级,它才会可见。</li>    </ul>    <pre>  <code class="language-java">public void draw(Canvas canvas) {      final Drawable d = getDrawable();      if (d != null && d.getLevel() != 0) {          d.draw(canvas);      }  }</code></pre>    <ul>     <li>分析ScaleDrawable的 onBoundsChange() 可看出 <strong>其内部mDrawable的大小和等级以及缩放比例的关系</strong> 。</li>    </ul>    <pre>  <code class="language-java">// iw常为0  final int iw = min ? d.getIntrinsicWidth() : 0;  // 1. MAX_LEVEL为10000,即等级的取值范围为0~10000。  // 2. 计算得到的最终w为其内部mDrawable最后显示的宽度。因为是-=,所以右边算数得到的值越大,则最终w就越小。  // 3. level越大,其内部mDrawable就越大。  // 4. ScaleDrawable的XML中所定义的缩放比例越大,即mState.mScaleWidth越大,则内部mDrawable就越小。  w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);</code></pre>    <h2><strong>ClipDrawable</strong></h2>    <ul>     <li>对应 <clip> 标签,用来裁剪另一个Drawable。</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <clip       xmlns:android="http://schemas.android.com/apk/res/android"      android:drawable="@[package:]drawable/drawable_resource"      android:clipOrientation="[vertical | horizontal]"      android:gravity="[top | bottom | left | right |          center_vertical | center_horizontal | center |          fill_vertical | fill_horizontal | fill |          clip_vertical | clip_horizontal]" /></code></pre>    <ul>     <li> <p>android:clipOrientation :表示裁剪方向,可选为水平和竖直。</p> </li>     <li> <p>android:gravity :表示对齐方式,需要和 clipOrientation 一起发挥作用。它的取值有下表各种选项,可用 | 来组合使用。</p> </li>    </ul>    <table>     <thead>      <tr>       <th>选项</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>top</td>       <td>放在容器的顶部,不改变大小。<br> 若为竖直裁剪,则从底部开始裁剪。</td>      </tr>      <tr>       <td>bottom</td>       <td>放在容器的底部,不改变大小。<br> 若为竖直裁剪,则从顶部开始裁剪。</td>      </tr>      <tr>       <td>left</td>       <td>这是默认值。放在容器的左边,不改变大小。<br> 若为水平裁剪,则从右边开始裁剪。</td>      </tr>      <tr>       <td>right</td>       <td>放在容器的右边,不改变大小。<br> 若为水平裁剪,则从左边开始裁剪。</td>      </tr>      <tr>       <td>center_vertical</td>       <td>在容器中竖直居中,不改变大小。<br> 若为竖直裁剪,则从上下同时裁剪。</td>      </tr>      <tr>       <td>center_horizontal</td>       <td>在容器中水平居中,不改变大小。<br> 若为水平裁剪,则从左右同时裁剪。</td>      </tr>      <tr>       <td>center</td>       <td>居中,不改变大小。<br> 若为竖直裁剪,则从上下同时裁剪。<br> 若为水平裁剪,则从左右同时裁剪。</td>      </tr>      <tr>       <td>fill_vertical</td>       <td>在竖直方向上填充容器。<br> 若为竖直裁剪,仅当等级为0时才能有裁剪行为。</td>      </tr>      <tr>       <td>fill_horizontal</td>       <td>在水平方向上填充容器。<br> 若为水平裁剪,仅当等级为0时才能有裁剪行为。</td>      </tr>      <tr>       <td>fill</td>       <td>完全填充容器。<br> 仅当等级为0时才能有裁剪行为。</td>      </tr>      <tr>       <td>clip_vertical</td>       <td>附加选项,表示竖直方向的裁剪。较少使用。</td>      </tr>      <tr>       <td>clip_horizontal</td>       <td>附加选项,表示水平方向的裁剪。较少使用。</td>      </tr>     </tbody>    </table>    <ul>     <li>ClipDrawable的裁剪程度由level控制,调用 setLevel() 可修改此值。其取值范围为0~10000。0表示完全裁剪,即整个Drawable都不可见;而10000表示不裁剪。也 可将level理解为可见区域大小,0表示可见区最小,10000表示可见区最大。</li>    </ul>    <h2><strong>自定义Drawable</strong></h2>    <ul>     <li> <p>Drawable的工作原理很简单,其核心就是 draw() 。系统会调用Drawable的 draw() 来绘制View的背景或ImageView的图像,于是我们可通过重写其 draw() 来实现自定义Drawable。</p> </li>     <li> <p>通常我们没有必要去自定义Drawable,因为无法在XML中使用自定义Drawable,这就降低了其使用范围。</p> </li>     <li> <p>创建自定义Drawable,必须重写其 draw() 、 setAlpha() 、 setColorFilter() 、 getOpacity() 等方法。以下为自定义Drawable示例:</p> </li>    </ul>    <pre>  <code class="language-java">/**   * 自定义Drawable   * Created by daking on 16/9/15.   */  public class CustomDrawable extends Drawable {      private Paint mPaint;        public CustomDrawable(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();          canvas.drawCircle(cx, cy, Math.min(cx, cy), mPaint);      }        @Override      public void setAlpha(int alpha) {          mPaint.setAlpha(alpha);          invalidateSelf();      }        @Override      public void setColorFilter(ColorFilter colorFilter) {          mPaint.setColorFilter(colorFilter);          invalidateSelf();      }        @Override      public int getOpacity() {          return PixelFormat.TRANSLUCENT;      }  }</code></pre>    <pre>  <code class="language-java">CustomDrawable drawable = new CustomDrawable(Color.BLUE);  imageView.setBackgroundDrawable(drawable);</code></pre>    <ul>     <li> <p>若自定义的Drawable有固有大小时,要重写 getIntrinsicWidth() 和 getIntrinsicHeight() 。因为这两个方法会影响到View的 wrap_content 布局。</p> </li>     <li> <p>注意,Drawable的内部大小不等于Drawable的实际区域大小。可通过 getBounds() 获得Drawable的实际区域大小,一般与它的View尺寸相同。</p> </li>    </ul>    <p> </p>    <p>来自:http://www.jianshu.com/p/fd358b03b64c</p>    <p> </p>