Android可绘制对象资源之shape和layer-list使用

Code4Android.jpg

前言

文章中内容多来自谷歌官方文档详戳,一些示例代码详戳GitHub,不喜请轻喷。

可绘制对象资源

可绘制对象资源是一般概念,是指可在屏幕上绘制的图形,以及可以使用 getDrawable(int) 等 API 检索或者应用到具有 android:drawable 和 android:icon 等属性的其他 XML 资源的图形。共有多种不同类型的可绘制对象:

  • 位图文件
    位图图形文件(.png、.jpg 或 .gif)。创建 BitmapDrawable。
  • 九宫格文件
    具有可拉伸区域的 PNG 文件,允许根据内容调整图像大小 (.9.png)。创建 NinePatchDrawable。
  • 图层列表
    管理其他可绘制对象阵列的可绘制对象。它们按阵列顺序绘制,因此索引最大的元素绘制在顶部。创建 LayerDrawable。
  • 状态列表
    此 XML 文件为不同状态引用不同位图图形(例如,按下按钮时使用不同的图像)。创建 StateListDrawable。
  • 级别列表
    此 XML 文件用于定义管理大量备选可绘制对象的可绘制对象,每个可绘制对象都分配有最大的备选数量。创建 LevelListDrawable。
  • 转换可绘制对象
    此 XML 文件用于定义可在两种可绘制对象资源之间交错淡出的可绘制对象。创建 TransitionDrawable。
  • 插入可绘制对象
    此 XML 文件用于定义以指定距离插入其他可绘制对象的可绘制对象。当视图需0要小于视图实际边界的背景可绘制对象时,此类可绘制对象很有用。
  • 裁剪可绘制对象
    此 XML 文件用于定义对其他可绘制对象进行裁剪(根据其当前级别值)的可绘制对象。创建 ClipDrawable。
  • 缩放可绘制对象
    此 XML 文件用于定义更改其他可绘制对象大小(根据其当前级别值)的可绘制对象。创建 ScaleDrawable
  • 形状可绘制对象
    此 XML 文件用于定义几何形状(包括颜色和渐变)。创建 ShapeDrawable。
    另请参阅动画资源文档,了解如何创建 AnimationDrawable。

注:颜色资源也可用作 XML 中的可绘制对象。例如,在创建状态列表可绘制对象时,可以引用 android:drawable 属性的颜色资源 (android:drawable="@color/green")

shape

shape顾名思义就是形状的意思,在我们平时的开发中,应用的频率也很高,该文件是一个xml文件,并放在drawale文件夹下如res/drawable/filename.xml, 那么引用方式也很简单了,我们一般在控件的background使用,如android:background="@drawable/filename"。所有属性如下

<?xml version="1.0" encoding="utf-8"?>
<!--   shape必须为根元素
xmlns:命名空间
android:shape指定形状类型
    rectangle:填充包含视图的矩形,当不写该属性时默认此形状
    oval:椭圆形状
    line:线形状,此形状需要 <stroke> 元素定义线宽
    ring:环形
当android:shape="ring"时,有可选属性
        android:innerRadius:尺寸。环内部(中间的孔)的半径
        android:innerRadiusRatio:浮点型。环内部的半径,以环宽度的比率表示。例如,如果 android:innerRadiusRatio="5",则内半径等于环宽度除以 5。此值被 android:innerRadius 覆盖。默认值为 9。
        android:thickness:环的厚度
        android:thicknessRatio:浮点型。环的厚度,表示为环宽度的比率。例如,如果 android:thicknessRatio="2",则厚度等于环宽度除以 2。此值被 android:innerRadius 覆盖。默认值为 3。
    需要注意的是,如果你使用了上面几个属性绘制一个圆,会发现在控件中并没有效果,我们还需要一个重要属性
        android:useLevel:布尔值。如果这用作 LevelListDrawable,则此值为“true”。这通常应为“false”,否则形状不会显示。
 -->
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape=["rectangle" | "oval" | "line" | "ring"] >
    <!--
    corners为形状产生圆角,仅当形状为矩形时使用
        android:radius:尺寸。所有角的半径,以尺寸值或尺寸资源表示。对于每个角,这会被以下属性覆盖。
        android:topLeftRadius:左上角的半径,以尺寸值或尺寸资源表示。
        android:topRightRadius:右上角的半径,以尺寸值或尺寸资源表示。
        android:bottomLeftRadius:左下角的半径,以尺寸值或尺寸资源表示。
        android:bottomRightRadius:右下角的半径,以尺寸值或尺寸资源表示
    -->
    <corners
        android:radius="integer"
        android:topLeftRadius="integer"
        android:topRightRadius="integer"
        android:bottomLeftRadius="integer"
        android:bottomRightRadius="integer" />
    <!--
        指定形状的渐变颜色,使用渐变时不要使用solid,否则会被覆盖,看不到效果
        android:angle:整型。渐变的角度(度)。0 为从左到右,90 为从上到上。必须是 45 的倍数。默认值为 0,如果写该值不是45的整数倍,将没有效果。
        android:centerX:浮点型。渐变中心的相对 X 轴位置 (0 - 1.0)。
        android:centerY:浮点型。渐变中心的相对 Y 轴位置 (0 - 1.0)。
        android:centerColor:颜色。起始颜色与结束颜色之间的可选颜色,以十六进制值或颜色资源表示。
        android:endColor:颜色。结束颜色,表示为十六进制值或颜色资源。
        android:gradientRadius:浮点型。渐变的半径。仅在 android:type="radial" 时适用。且radial时必须有该属性,否则无效果
        android:startColor:颜色。起始颜色,表示为十六进制值或颜色资源。
        android:type:要应用的渐变图案的类型。有效值为
                      "linear"  线性渐变。这是默认值。
                      "radial"  径向渐变。起始颜色为中心颜色。
                      "sweep"   流线型渐变。
        android:useLevel:布尔值。如果这用作 LevelListDrawable,则此值为“true”。
    -->
    <gradient
        android:angle="integer"
        android:centerX="float"
        android:centerY="float"
        android:centerColor="integer"
        android:endColor="color"
        android:gradientRadius="integer"
        android:startColor="color"
        android:type=["linear" | "radial" | "sweep"]
        android:useLevel=["true" | "false"] />
    <!--
        要应用到包含视图元素的内边距(这会填充视图内容的位置,而非形状)。
        android:left:尺寸。左内边距,表示为尺寸值或尺寸资源
        android:top:尺寸。上内边距,表示为尺寸值或尺寸资源
        android:right:尺寸。右内边距,表示为尺寸值或尺寸资源
        android:bottom:尺寸。下内边距,表示为尺寸值或尺寸资源
    -->
    <padding
        android:left="integer"
        android:top="integer"
        android:right="integer"
        android:bottom="integer" />
    <!--
        指定形状的大小
        注:默认情况下,形状按照此处定义的尺寸按比例缩放至容器视图的大小。在 ImageView 中使用形状时,可通过将 android:scaleType 设置为 "center" 来限制缩放。
    -->
    <size
        android:width="integer"
        android:height="integer" />
    <!---
        用于填充形状的颜色
        android:color:颜色。应用于形状的颜色
        ->
    <solid
        android:color="color" />
    <!--
        形状的笔划中线。即形状的边框
        android:width:尺寸。线宽,以尺寸值或尺寸资源表示。
        android:color:颜色。线的颜色,表示为十六进制值或颜色资源。
        android:dashGap:尺寸。短划线的间距,以尺寸值或尺寸资源表示。仅在设置了 android:dashWidth 时有效。
        android:dashWidth:尺寸。每个短划线的大小,以尺寸值或尺寸资源表示。仅在设置了 android:dashGap 时有效。
-->
    <stroke
        android:width="integer"
        android:color="color"
        android:dashWidth="integer"
        android:dashGap="integer" />
</shape>

简单效果图


这里写图片描述

xml实现文件:

<?xml version="1.0" encoding="utf-8"?><!--    -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners
        android:radius="15dp"
        android:topLeftRadius="3dp" />
    <gradient
        android:centerColor="#00ff00"
        android:centerX="0.5"
        android:centerY="0.5"
        android:endColor="#0000ff"
        android:gradientRadius="25dp"
        android:startColor="#ff0000"
        android:type="radial" />
    <!--    <solid
            android:color="#00ff00"/>-->
    <size
        android:width="10dp"
        android:height="10dp" />
    <padding
        android:bottom="15dp"
        android:left="15dp"
        android:right="15dp"
        android:top="15dp" />

</shape>

在xml文件实现shape和用java代码实现大同小异,他们命名规则都是相对应的,可参照官方API文档,戳此链接查看

图层列表layer-list

LayerDrawable 是管理其他可绘制对象阵列的可绘制对象。列表中的每个可绘制对象按照列表的顺序绘制,列表中的最后一个可绘制对象绘于顶部。每个可绘制对象由单一 <layer-list> 元素内的 <item> 元素表示。我们需要注意的是layer-list中有item的先后顺序会影响展示效果,不同顺序的效果可能大相径庭,因为,后面的item总是在之前的item之上并覆盖显示。

<?xml version="1.0" encoding="utf-8"?>
<!-- 
必备。这必须是根元素。包含一个或多个 <item> 元素。
xmlns:android:字符串。必备。定义 XML 命名空间,其必须是 "http://schemas.android.com/apk/res/android"。
-->
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <!--
    定义要放在图层可绘制对象中由其属性定义的位置的可绘制对象。必须是 <selector> 元素的子项。接受子 <bitmap> 元素。
    android:drawable:可绘制对象资源。必备。引用可绘制对象资源。
    android:id:资源 ID。此可绘制对象的唯一资源 ID。要为此项新建资源 ID,请使用以下形式:"@+id/name"。加号表示应创建为新 ID。可以使用此 ID 检索和修改具有 View.findViewById() 或 Activity.findViewById() 的可绘制对象。
    android:top:整型。顶部偏移(像素)。
    android:right:整型。右边偏移(像素)。
    android:bottom:整型。底部偏移(像素)。
    android:left:整型。左边偏移(像素)。
    -->
    <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" />
</layer-list>

默认情况下,所有可绘制项都会缩放以适应包含视图的大小。因此,将图像放在图层列表中的不同位置可能会增大视图的大小,并且有些图像会相应地缩放。为避免缩放列表中的项目,请在 <item> 元素内使用 <bitmap> 元素指定可绘制对象,并且对某些不缩放的项目(例如 "center")定义重力。例如,以下 <item> 定义缩放以适应其容器视图的项目:

<item android:drawable="@drawable/image" />
为避免缩放,以下示例使用重力居中的 <bitmap> 元素:

<item>
  <bitmap android:src="@drawable/image"
          android:gravity="center" />
</item>

layer-list的强大之处在于,它的每一个item都可以是一个shape.例如,开始我们的控件有一个需求将控件显示有一个1px边框的矩形,如下图

这里写图片描述

那么我们一个可以通过一个shape就可以实现,如下

<?xml version="1.0" encoding="utf-8"?><!--    -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/white" />
    <stroke
        android:width="1px"
        android:color="#9b9b9b" />
    <padding
        android:bottom="5dp"
        android:left="8dp"
        android:right="8dp"
        android:top="5dp" />
</shape>

那么如果我们新的需求变更了,左右上边框不展示了,即只展示下面的一条线,那么怎么实现呢,可能大家最常用的就是用一个1px高度的view加个背景色填充,但是如果我们想显示左边和边的边框呢?那么需要再加View,布局可能会很复杂。可能你也会说,shape可以指定android:shape="line"来绘制一条线,那么咱来试试。

这里写图片描述

这就是实现的效果图,发现,线是在中间,这肯定不是我们想要的效果,我们想要的效果是线在控件的最下方,其实此时shape已经不能满足我们的需求了,但是layer-list可以实现,想有哪个边框都可以。如下实现

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#9b9b9b" />
        </shape>
    </item>
    <item android:bottom="1px">
        <shape>
            <solid android:color="@color/white" />
            <padding
                android:bottom="5dp"
                android:left="8dp"
                android:right="8dp"
                android:top="5dp" />
        </shape>
    </item>
</layer-list>

效果图:

这里写图片描述

那么如果我们想在控件左边和下面显示边框线,那么在上述lsyer-list中第二个item加一句 android:left="1px"就可以实现了。如下图

这里写图片描述

是不是比用view填充方便呢,关于java代码实现可以直接去参考官方文档,详情戳此链接。今天就介绍到这,有问题欢迎指出,Have a wonderful day.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容