Connor学Android - Drawable

在这里插入图片描述

Learn && Live

虚度年华浮萍于世,勤学善思至死不渝

前言

Hey,欢迎阅读Connor学Android系列,这个系列记录了我的Android原理知识学习、复盘过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/8mtej,话不多说我们马上开始!

1.Drawable简介

Drawable一般通过XML定义,也可以通过代码来创建具体的Drawable对象。在Android的设计中,Drawable是一个抽象的类,是所有Drawable对象的基类,每个具体的Drawable都是它的子类,比如ShapeDrawable、BitmapDrawable等

Drawable可以通过 getIntrinsicWidth 和 getIntrinsicHeight 获取其内部宽高,但不是所有Drawable都有内部宽高,如一个颜色所形成的Drawable;另外,Drawable的内部宽高不等同于它的大小,当用作View的背景时,Drawable会被拉伸至View的同等大小

2.Drawable分类

2.1 BitmapDrawable

对应标签 <bitmap> ,表示一张图片,在实际开发中,可以直接引用原始的图片,也可以通过XML的方式来描述它

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@color/colorPrimary"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:gravity="center"
    android:mipMap="false"
    android:tileMode="disabled"
    />

android:src:图片的资源id

android:antialias:是否开启图片抗锯齿,开启后会让图片变得平滑,应该开启

android:dither:是否开启抖动效果,可以让高质量的图片在低质量的屏幕上保持较好显示效果,应该开启

android:filter:是否开启过滤效果,当图片被拉伸或压缩时仍能保持较好的显示效果

android:gravity:图片小于容器的尺寸时可用来对定位图片,如top、bottom等

android:minMap:纹理映射,默认值为false,日常开发不常用

android:tileMode:平铺模式,默认值为disable

  • disable:关闭平铺模式
  • repeat:水平和竖直方向上的平铺效果
  • mirror:水平和竖直方向上的镜面投影效果
  • clamp:图片四周的像素会扩展到周围区域
2.2 NinePatchDrawable

对应标签 <nine-patch> ,表示的是一张.9格式的图片,可以自动地根据所需的宽高进行相应的缩放且保证不失真

<?xml version="1.0" encoding="utf-8"?>
<nine-patch
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@color/colorPrimary"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:gravity="center"
    android:mipMap="false"
    android:tileMode="disabled"
    />
2.3 ShapeDrawable

对应标签 <shape> ,通过颜色来构造的图形,既可以是纯色的图形,也可以是具有渐变效果的图形

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <corners
        android:radius="10dp"
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp"
        android:bottomLeftRadius="10dp"
        android:bottomRightRadius="10dp"/>
    <gradient
        android:angle="45"
        android:centerX="30"
        android:centerY="30"
        android:centerColor="@color/colorAccent"
        android:endColor="@color/colorPrimary"
        android:startColor="@color/colorPrimaryDark"
        android:gradientRadius="20"
        android:type="linear"
        android:useLevel="true" />
    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp" />
    <size
        android:width="200dp"
        android:height="200dp" />
    <solid
        android:color="@color/colorPrimary"/>
    <stroke
        android:width="10dp"
        android:color="@color/colorAccent"
        android:dashWidth="5dp"
        android:dashGap="3dp"/>

</shape>

<shape>标签创建的Drawable,其实体类实际上是GradientDrawable

android:shape:表示图形形状,可选:rectangle(默认)、oval、line、ring,其中line和ring必须通过<stroke>定义线的宽度和颜色
ring包含5个特殊属性:android:innerRadius、android:thickness、android:innerRadiusRatio、android:thicknessRatio、android:useLevel

在这里插入图片描述
<cornors>

表示shape的四个角的圆角角度,仅适用于矩形shape,用px表示,属性有android:radius、android:topLeftRadius、android:topRightRadius、android:bottomLeftRadius、android:bottomRightRadius

<gradient>:

表示渐变效果,与<solid>纯色填充互斥

  • android:angle:渐变角度,默认为0,必须是45的整数倍,0表示从左到右,90表示从下到上
  • android:centerX:渐变中心点的横坐标
  • android:centerY:渐变中心点的纵坐标
  • android:startColor:渐变起始色
  • android:centerColor:渐变中间色
  • android:endColor:渐变结束色
  • android:gradientRadius:渐变半径,仅当android:type="radial"时有效
  • android:useLevel:一般为false,StateListDrawable时为true
  • android:type:渐变的类别,linear(线性渐变)、radial(径向渐变)、sweep(扫描线渐变),默认为linear

在这里插入图片描述
<solid>

纯色填充,可通过android:color指定颜色

<stroke>

shape描边,可以是实线或虚线

  • android:width:描边宽度
  • android:color:描边颜色
  • android:dashWidth:虚线宽度
  • android:dashGap:虚线线段之间的间隔

如果 dashWidth 和 dashGap 中任何一个为0,则虚线效果不能生效

<padding>

实际上是margin,是包含当前shape的View的空白

<size>

指定shape的固有宽高。shape在默认情况下没有固定宽高,此时 getIntrinsicWidth 和 getIntrinsicHeight 返回-1;而通过<size>指定固定宽高,shape就有了固定宽高,但作为View的背景时,shape还会被拉伸或压缩为View的大小

2.4 LayerDrawable

对应标签 <layer-list>,表示一种层次化的Drawable集合,不同的Drawable放置在不同的层上面从而达到一种叠加效果
一个layer-list中可以包含多个item,每个item可以通过android:drawable引用一个Drawable资源,在一个layer-list中,下面的item会覆盖上面的item,下面是模拟实现微信输入框的案例

<?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>
2.5 StateListDrawable

对应标签 <selector> ,表示Drawable集合,每个Drawable对应View的一种状态,系统根据View的状态选择合适的Drawable。主要用于设置可单击的View的背景,如Button

一般来说,默认的item都应放在selector的最后一个且不附带任何状态,这样当上面的item都无法匹配View的当前状态时,会选择这个默认的item,因为默认的item不附带状态限制,即可以匹配任何状态

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="false"      // StateListDrawable的固有大小是否根据状态而改变,默认false=根据状态而改变
    android:dither="true"             // 是否开启抖动-让高质量图片在低质量屏幕上依旧效果好,默认true开启
    android:variablePadding="false"   // padding是否根据状态的改变而改变,不建议开启(false)
    >
    <item android:state_pressed="true"  // Button被按下后却没有松开的状态
        android:drawable="@color/colorAccent"/>
    <item android:state_focused="true"  // View获取了焦点
        android:drawable="@color/colorPrimary"/>
    <item android:state_selected="true" // 用户选择了View
        android:drawable="@color/colorPrimary"/>
    <item android:state_checked="true" // 用户选中了View,一般用于CheckBox这类在选中和没有选中状态之间切换的View
        android:drawable="@drawable/ic_launcher_background"/>
    <item android:state_enabled="true" // View处于可用状态
        android:drawable="@drawable/ic_launcher_foreground"/>
    <item android:drawable="#FFFFFF"/> // 默认Drawable: 按顺序向下匹配,需要放在最下方,因为可以匹配任何状态
</selector>
2.6 LevelListDrawable

对应标签 <level-list> ,表示一个Drawable集合,每个Drawable都有一个level,根据不同level切换Drawable

level可以通过 android:minLevel 和 android:maxLevel 指定,范围0-10000,默认为0

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:minLevel="0" android:maxLevel="10" android:drawable="@drawable/d1" />
    <item android:minLevel="11" android:maxLevel="20" android:drawable="@drawable/d2" />
    <item android:minLevel="21" android:maxLevel="30" android:drawable="@drawable/d3" />
    <item android:minLevel="31" android:maxLevel="40" android:drawable="@drawable/d4" />
</level-list>
2.7 TransitionDrawable

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

获得背景的 TransitionDrawable 后,通过 startTransition 和 reverseTransition 方法实现效果和逆过程

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/transition_drawable"
        android:drawable="@drawable/ic_launcher"
        android:top="10dp"    // 四周的偏移量
        android:bottom="10dp"
        android:right="10dp"
        android:left="10dp"/>
    <item android:drawable="@drawable/ic_launcher_round" />
</transition>
2.8 InsetDrawable

对应标签 <inset> ,可以将其他Drawable内嵌到自己中,并留出一定间距。当一个View希望自己的背景比自己的实际区域小的时候,可以通过InsetDrawable实现

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:insetTop="10dp"     // 四周间距
    android:insetBottom="10dp"
    android:insetLeft="10dp"
    android:insetRight="10dp">
</inset>
2.9 ScaleDrawable

(1)对应标签 <scale>

(2)根据自己的等级level(0~10000)将指定的Drawable缩放到一定比例

(3)android:scaleHeight="70%"用于指定宽高的缩放比例为原来的30%

(4)ScaleDrawable的level为0,不可见。为10000时,不缩放。

(5)level越大,内部Drawable就越大;缩放比例越大,内部Drawable就越小

(6)android:scaleGravity属性和gravity属性完全一致

<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:scaleGravity="center"
    android:scaleHeight="70%"
    android:scaleWidth="70%">
</scale>
2.10 ClipDrawable

(1)对应标签 <clip>

(2)根据等级level来裁剪另一个Drawable,裁剪方向可以通过 android:clipOrientation 和 android:gravity 控制

(3)level范围0-10000,0表示完全裁剪,即不可见;10000表示不裁剪

(4)clipOrientation有水平、竖直两个方向,gravity与clipOrientation组合结果如下表

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ConnorYan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值