原文地址:https://github.com/codepath/android_guides/wiki/Drawables
绘制资源是一个通用概念,可绘制到屏幕的图形。可绘用于定义形状,颜色,边界,渐变等人然后可以施加到次一个活动范围内。这通常用于定制所显示的特定视图或环境内的视图的图形。可绘倾向于在XML中被定义,并且可以被应用到通过XML或Java的图。对于默认可绘制每一个Android版 本的列表,请参阅androiddrawables网站作为一个很好的参考。
用法
可绘可以是一个压倒性的最初的话题,因为在不同的情况下,如绘图使用形状绘制许多种类,设定状态的行为按钮,创建伸缩按钮的背景和复合创建图层绘制。
至少有17种可绘制的,但有4个是最重要的理解:
- StateList Drawables -定义可绘的列表,以用于不同的状态
- LayerList Drawables -定义可绘组的列表连成一个复合结果
- NinePatch Drawables -与伸缩区域的PNG文件,允许适当调整大小
-
Shape Drawables -定义了诸如描边性质的形状,填充
让我们来探讨这些绘制文件类型逐一来看看使用的例子。
绘制形状
的形状绘制对象是定义的几何形状,其中包括颜色和渐变的XML文件。这被用来创建一个复杂的形状,然后可以附作为布局的背景或在屏幕上的图。例如,你可以使用一个形状绘制改变按钮背景的形状,边框和梯度。
A字形是一个简单的组合来描述一个背景属性的集合。形状可以用属性来描述,如边角
舍入,渐变
为背景,填充
的间距,坚实的
背景颜色和中风
的边界。
纯色形状
下面是绘制一个圆角矩形的边框的例子RES /布局/绘制/ solid_color_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 = "4dp" /> <stroke android:width = "4dp" android:color = "#C1E1A6" /> <solid android:color = "#118C4E" /> <padding android:left = "20dp" android:top = "20dp" android:right = "20dp" android:bottom = "20dp" /> </shape>
然后应用到使用一个TextView 背景
属性:
<pre name="code" class="html"><TextView
android:layout_width = " wrap_content "
android:layout_height = " wrap_content "
android:background = "@drawable/solid_color_shape"
android:textColor = "#ffffff"
android:text = "@string/hello_world" />
所得效果是这样的:
Gradient Colored Shapes
形状也支持渐变背景以及支持诸如性能startColor
,centerColor
,endColor
,angle
。不同梯度如径向,直链或扫描可以使用被选择的类型
属性。
下面是在指定的简单线性渐变形状的例子RES /布局/绘制/ gradient_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 = "4dp" /> <stroke android:width = "1dp" android:color = "#0078a5" /> <gradient android:startColor = "#0078a5" android:endColor = "#00adee" android:angle = "90" /> <padding android:left = "8dp" android:top = "2dp" android:right = "8dp" android:bottom = "2dp" /> </shape>
应用到一个按钮,将所得视图看起来像:
您还可以设置径向渐变型带:
<?xml version = "1.0" encoding = "utf-8" ?> <shape xmlns:android = "http://schemas.android.com/apk/res/android" android:shape = " rectangle " > <corners android:radius = "4dp" /> <stroke android:width = "4dp" android:color = "#CCFFFF" /> <gradient android:startColor = "#0078a5" android:endColor = "#CCFFFF" android:gradientRadius = "250" android:type = " radial " /> <padding android:left = "30dp" android:top = "30dp" android:right = "30dp" android:bottom = "30dp" /> </shape>
并应用到一个TextView,这看起来像:
使用纯色形状和梯度我们可以自定义的按钮,布局和其他视图的外观,而无需使用任何图像。需要注意的是自定义形状可以在运行时使用创建其他形状绘制类型使用PathShape
和ArcShape
。
State List
StateListDrawable是使用几种不同的图像来表示相同的图形,根据对象的状态中的XML定义的可绘制对象。例如,一个按钮控件可以在几种不同的状态(压,突出重点,或两者都不是),并使用状态列表绘制的一个存在,你可以为每个国家不同的背景图像。国家列表支持不同的视图状态,如安卓state_pressed
,安卓state_focused
,安卓state_enabled
,安卓state_selected
,等等。下图显示了一切可以代表的主要国家:
例如,一个State List XML为按钮背景可能看起来像一个文件下面,如RES /绘制/ selector_button_bg
:
<?xml version = "1.0" encoding = "utf-8" ?> <selector xmlns:android = "http://schemas.android.com/apk/res/android" > <item android:state_pressed = "true" android:state_enabled = "true" android:drawable = "@drawable/button_pressed" /> <item android:state_focused = "true" android:state_enabled = "true" android:drawable = "@drawable/button_focused" /> <item android:state_enabled = "true" android:drawable = "@drawable/button_enabled" /> </selector>
现在,当视图(即键)时,或专注,用于视图的绘制将发生相应的变化。请注意,任何视图可以有一个状态选择,但最常见的用途是按钮和列表视图项。也有彩色状态选择器允许基于视图状态被选择的颜色,如在一个文件名 为资源/颜色/ button_text.xml
:
<?xml version = "1.0" encoding = "utf-8" ?> <selector xmlns:android = "http://schemas.android.com/apk/res/android" > <item android:state_pressed = "true" android:color = "#ffff0000" /> <item android:state_focused = "true" android:color = "#ff0000ff" /> <item android:color = "#ff000000" /> </selector>
和施加到接受颜色值如任何字段TEXTCOLOR
在布局文件的一个按钮的属性:
<Button android:layout_width = " fill_parent " android:layout_height = " wrap_content " android:text = "@string/button_text" android:textColor = "@color/button_text" />
使用状态列表可以让我们轻松定义为按下,检查,启用或其他相关响应状态动态视图。
创建一个图层列表
一个LayerDrawable是管理其他可绘制的数组绘制的对象。列表中的每个可绘制被绘制在列表中的最后一个列表可拉伸的顺序被绘制在顶部。每个绘制由一个代表的<item>
元素一个内部<图层列表>
元素。
该LayerList可用于绘制多个其他可绘(形状,图像等),以及它们在关系定位到彼此。这些层被放置在彼此的顶部由默认的最后一个项目被绘制在顶部。然后图层可以有自己的坐标,使用移动左
,右
,顶部
和底部的
性质。
常见的用例层列表包括:
对于一个简单的例子,下面的层列表绘制了几个形状相对彼此:
<?xml version = "1.0" encoding = "utf-8" ?> <layer-list xmlns:android = "http://schemas.android.com/apk/res/android" > <item> <shape android:shape = " rectangle " > <stroke android:width = "1dp" android:color = "#585858" /> <solid android:color = "#FF9009" /> <padding android:bottom = "1dp" /> </shape> </item> <item android:left = "10dp" android:top = "20dp" android:bottom = "20dp" android:right = "150dp" > <shape android:shape = " oval " > <stroke android:width = "1dp" android:color = "#ffffff" /> <solid android:color = "#118C4E" /> <padding android:bottom = "1dp" /> </shape> </item> <item android:left = "150dp" android:top = "20dp" android:bottom = "20dp" android:right = "10dp" > <shape android:shape = " rectangle " > <stroke android:width = "1dp" android:color = "#ffffff" /> <solid android:color = "#C1E1A6" /> <padding android:bottom = "1dp" /> </shape> </item> </layer-list>
这导致了以下内容:
请记住,在一个项目LayerList也可以是图像或任何其他类型的可绘制的。您可以使用它来 创建更复杂的图纸和多重叠加在可绘彼此顶部。在看到更多的例子官方的文档。
拉伸九补丁图片
一个NinePatch是一个PNG图像,可以在其中定义拉伸拉伸区域时,视图中的含量超出了正常的图像边界。您通常这种类型的图像作为指定的视图,它的宽度设置为背景WRAP_CONTENT
。最常见的用途是一个按钮,具有基于内显示的文本舒展。
NinePatch是具有图像.9.png
文件扩展表示,这是一个可拉伸的PNG图像。该文件是没有从不同的是将添加细黑线来表示垂直和水平“可拉伸”和“补”的区域为图像的通常的PNG文件不同。机器人将不会显示这些引导线,其用于确定如何图像应该被渲染。
9补丁图像的一例嵌入下面(左侧是9patch图形,右是在一个应用程序使用的一个例子):
一个NinePatch定义并保存在绘制
文件夹,并设置背景的作品一样具有任何图像:
<Button android:layout_width = " wrap_content " android:layout_height = " wrap_content " android:text = "Submit" android:background = "@drawable/button_background" />
Android的工作室配备了直接编辑9补丁文件的能力。您的PNG文件只需要保存与.9.png
扩展在绘制
文件夹,和9补丁编辑器将显示而不是正常的图像编辑器。你可以使用鼠标来选择要拉伸的区域(使用Shift键并单击的同时拖动鼠标擦除的区域),并在右边显示的图像是如何将取决于中的文本渲染的预览窗格。
需要可拉伸区域要定义的左侧和顶线。为了避免拉伸,在上面的例子中这个讲话泡沫的箭头,我们这方面的定义之外的地区。右边和底部行定义在哪里文字即可充满。无底线例如,文本不会填满延伸区域的整个宽度和可能无法正确居中。
你也可以使用draw9patch工具来创建特殊的九片图像,也可以使用在线9补丁工具。您可以检查出漂亮的9贴片按键大现成的例子的例子。
看到这个简单的指南以获取更多信息。您也可以参考官方九补丁文档。
自定义按钮
让我们来看看使用定制以可绘制的执政风格和按下的状态的按钮的终端到终端的例子。
创建一个自定义的按钮至少需要一个状态列表绘制结合的形状绘制。首先,我们来创建形状绘制它代表了“默认”按钮背景RES /绘制/ nice_button_enabled.xml
:
<?xml version = "1.0" encoding = "utf-8" ?> <shape xmlns:android = "http://schemas.android.com/apk/res/android" android:shape = " rectangle " > <gradient android:startColor = "#0078a5" android:endColor = "#00adee" android:angle = "90" /> <padding android:left = "15dp" android:top = "1dp" android:right = "15dp" android:bottom = "1dp" /> <stroke android:width = "1dp" android:color = "#0076a3" /> <corners android:radius = "8dp" /> </shape>
让我们再创建一个样式(组视图属性),其中包括设置在后台RES /价值/ styles.xml
:
<style name = "NiceButton" parent = "@android:style/Widget.Button" > <item name = "android:gravity" > center_vertical|center_horizontal </item> <item name = "android:textColor" > #FFFFFF </item> <item name = "android:background" > @drawable/nice_button_enabled </item> <item name = "android:textSize" > 16sp </item> <item name = "android:textStyle" > bold </item> <item name = "android:focusable" > true </item> <item name = "android:clickable" > true </item> </style>
这现在表示形状与在默认状态的按钮的背景以及所有其他的属性。我们可以通过设置应用该样式
的按钮:
<Button android:id = "@+id/btnGo" style = " @style / NiceButton " android:layout_width = " wrap_content " android:layout_height = " wrap_content " />
如果我们运行的是,我们将看到以下按钮:
现在该按钮显示了很好,但没有任何“按下”或“集中”的状态。要做到这一点,我们需要创建一个状态表绘制描述可绘制在每个国家RES /绘制/ states_nice_button.xml
:
<?xml version = "1.0" encoding = "utf-8" ?> <selector xmlns:android = "http://schemas.android.com/apk/res/android" > <item android:state_pressed = "true" android:state_enabled = "true" android:drawable = "@drawable/nice_button_pressed" /> <item android:state_focused = "true" android:state_enabled = "true" android:drawable = "@drawable/nice_button_focused" /> <item android:state_enabled = "true" android:drawable = "@drawable/nice_button_enabled" /> </selector>
这说明(,按下并专注默认)在所有三个大国按钮的外观。现在,我们需要创建两个形状绘制状态。一个用于RES /绘制/ nice_button_pressed.xml
,另一个用于RES /绘制/ nice_button_focused.xml
:
<?xml version = "1.0" encoding = "utf-8" ?> <shape xmlns:android = "http://schemas.android.com/apk/res/android" android:shape = " rectangle " > <gradient android:startColor = "#00adee" android:endColor = "#0078a5" android:angle = "90" /> <padding android:left = "15dp" android:top = "1dp" android:right = "15dp" android:bottom = "1dp" /> <stroke android:width = "1dp" android:color = "#0076a3" /> <corners android:radius = "8dp" /> </shape>
对于本指南中压和聚焦状态会出现相同的,但当然,这些可能是不同的视觉状态为好。现在,我们需要改变风格来使用RES /绘制/ states_nice_button.xml
:
<style name = "NiceButton" parent = "@android:style/Widget.Button" > <item name = "android:gravity" > center_vertical|center_horizontal </item> <item name = "android:textColor" > #FFFFFF </item> <item name = "android:background" > @drawable/states_nice_button </item> <item name = "android:textSize" > 16sp </item> <item name = "android:textStyle" > bold </item> <item name = "android:focusable" > true </item> <item name = "android:clickable" > true </item> </style>
现在我们有一个按钮,有一个很好的形状绘制背景时无需单独的图像资源按所有更改可视状态!一定要检查出按钮生成一个工具,允许用户通过Web界面使自己的按钮。
自定义的ListView
另一种常见的任务是定制的项目在ListView的外观。首先,让我们创建基本的ListView和里面的填充字符串项。首先,布局XML在项目RES /布局/ item_simple.xml
:
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:padding="5dp" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" />
接下来,让我们设置一个活动的基本的ListView XML:
<ListView android:id = "@+id/lvTest" android:layout_width = " match_parent " android:layout_height = " wrap_content " > </ListView>
然后填充物品的ListView:
ArrayList<String> items = new ArrayList<String>(); for (int i = 1; i < 8; i++) { items.add("Item " + i); } ArrayAdapter<String> aItems = new ArrayAdapter<String>(this, R.layout.item_simple, items); lvTest = (ListView) findViewById(R.id.lvTest); lvTest.setAdapter(aItems);
这将导致以下默认样式的ListView:
现在,让我们来添加自己的造型到ListView。让我们添加一个默认的渐变和梯度挤压,改项目之间的分隔符的颜色,并添加边框ListView控件。首先,让我们添加形状渐变背景在默认状态RES /绘制/ gradient_bg.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#f1f1f2" android:centerColor="#e7e7e8" android:endColor="#cfcfcf" android:angle="270" /> </shape>
然后换压渐变背景RES /绘制/ gradient_pressed_bg.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#C1E1A6" android:endColor="#118C4E" android:angle="270" /> </shape>
然后让我们创建一个状态列表,它描述了可绘制在各种名单中的国家使用RES /绘制/ states_selector_list.xml
:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/gradient_bg" /> <item android:state_pressed="true" android:drawable="@drawable/gradient_pressed_bg" /> <item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/gradient_pressed_bg" /> </selector>
接下来,让我们设置为使用一个形状绘制的ListView我们的边界RES /绘制/ list_border.xml
通过设置“中风”属性:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <stroke android:width="1dp" android:color="#b5b5b5" /> <solid android:color="#00000000" /> </shape>
现在,让我们每个这些XML可绘的适用于各种元件。首先,让我们在后台添加到列表中的项目本身和调整RES /布局/ item_simple.xml
:
<TextView xmlns:android="http://schemas.android.com/apk/res/android" ... android:background="@drawable/states_selector_list" />
注意,背景
属性被设置到状态列表以应用默认背景为项。接下来,让我们添加边框和选择的国家在活动中布局文件现有的ListView:
<ListView ... android:padding="1dp" android:divider="#b5b5b5" android:dividerHeight="1dp" android:background="@drawable/list_border" android:listSelector="@drawable/states_selector_list" > </ListView>
在这里,我们已经定制了分
颜色和dividerHeight
以及在后台
应用边界,listSelector
管理状态,当一个项目被按下。有了这个全部到位,我们定制的ListView现在看起来像:
现在,我们已经成功地定制我们的ListView的外观和它使用一系列可绘制的项目。您可以使用这些技术,使一个名单看,但是你想根据您的应用需求。
可绘制在运行时
我们可以在运行时在我们的Java代码通过访问应用了一个绘制视图的背景访问可绘。例如,对于这层列表RES /可绘制/ message_bubble.xml
:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/outerRectangle"> <shape android:shape="rectangle" > <solid android:color="#FF00FF" /> </shape> </item> <item android:left="10dp"> <shape android:shape="rectangle" > <solid android:color="#ffccd2" /> </shape> </item> </layer-list>
然后,我们可以访问outerRectangle
从我们的活动中被指定ID:
//获取绘制图层列表从背景 LayerDrawable bubble = (LayerDrawable) tvFoo.getBackground(); //改变绘制的纯色 bubble.findDrawableByLayerId(R.id.outerRectangle); outerRect.setColor(Color.parseColor("#2f8f22"));
注意,形状被访问作为GradientDrawable
这里,即使形状是纯色。
其他类型的可绘制对象
- LevelList -被拉伸,管理着数交替可绘制的,每个分配的最大数值。
- TransitionDrawable -可以淡入淡出的可绘制对象,两个可绘制资源之间。用于两个可绘制动画之间。
- InsetDrawable -在XML中定义的可绘制的镶石另一个绘制由指定的距离。当一个视图需要一个背景比视图的实际范围较小,这非常有用。
- ClipDrawable -另一个可绘制在此基础上绘制对象的当前水平剪辑XML定义的绘制。最常用于实现像进度条。
- ScaleDrawable -在XML中所述的可拉伸,改变的是根据它的电流电平的另一可拉伸的大小。
工具
参考
- http://developer.android.com/guide/topics/resources/drawable-resource.html
- http://www.vogella.com/articles/AndroidDrawables/article.html
- http://developer.android.com/reference/android/graphics/drawable/Drawable.html
- http://android-dev-tips-and-tricks.blogspot.com/2012/08/xml-drawables-part-i.html
- http://androidcookbook.com/Recipe.seam;jsessionid=8BED36512503CA63614CA9237248CBE7?recipeId=3307
- http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
- http://cyrilmottier.com/2011/08/08/listview-tips-tricks-3-create-fancy-listviews/
- http://bnotions.com/efficient-use-of-drawables-to-develop-a-dynamic-ui-on-android/
- http://androiddrawables.com/
- http://nick.perfectedz.com/android-layerlist-tip/