Android – Drawable 详解

您所在的位置:网站首页 android桌面图标只放一个drawable尺寸可以吗 Android – Drawable 详解

Android – Drawable 详解

2023-11-20 07:31| 来源: 网络整理| 查看: 265

很早看过这篇文章,并做了笔记,后来看到群里的小伙伴有问相关Drawable的问题,就把这篇翻译过来的文章给放出来了。大家一起学习,一起进步。

前言

Drawable是可以绘制到屏幕上的图形。 Drawable用于定义形状,颜色,边界,渐变等,然后将其应用于Activity中的View。 这通常用于自定义显示在特定View。 Drawable倾向于在XML中定义,然后可以通过XML或Java代码应用于View。 有关Android的每个版本的默认Drawable列表,请参考androiddrawables网站。

用法

在不同情况下有很多可绘制的类型,设置按钮的状态行为,创建可伸缩的按钮背景和创建复合可绘制图层。 至少有17种可绘制类型,但有五个最重要的: ① Shape Drawables - 定义具有例如:stroke(描边),fill(填充)和padding(内边距)等属性的形状 ② StateList Drawables - 定义用于不同状态的Drawable ③ LayerList Drawables - 定义分组在一起成为复合结果的Drawable ④ NinePatch Drawables - 具有可伸缩区域的PNG图片,以允许适当调整大小 ⑤ Vector Drawables - 定义复杂的基于XML的矢量图像

下面让我们一一介绍它们的使用方法

Shape

Shape Drawable是一个XML文件,它定义了几何形状,包括颜色和渐变。这用于创建一个复杂的形状,然后可以作为布局或视图的背景附加在屏幕上。例如,可以使用可绘制的形状来更改按钮背景的形状,边框和渐变。

一个形状只是一个属性的集合,被合并来描述一个背景。形状可以用属性来描述,如圆角,背景渐变,间距填充,背景颜色固定,描边等。

纯色 Shapes

下面是一个绘制带有边框的圆角矩形的示例:

然后在TextView的background属性里应用:

结果看起来像下面这样:

注意,drawables可以应用于任何View及ViewGroup,通常是通过background属性来设置Drawable资源的。

渐变色的 Shapes

形状也支持 gradients backgrounds(渐变背景)支持的属性,如startColor,centerColor,endColor,角度。可以使用类型属性选择不同的渐变,如径向,线性或扫描。

下面是一个简单的线性渐变形状的例子:

结果看起来像下面这样:

你还可以使用以下设置径向类型渐变:

应用于TextView时,看起来像下面这样:

使用纯色形状和渐变,我们可以自定义按钮,布局和其他视图的外观,而不需要使用任何图片。请注意,可以使用PathShape和ArcShape在运行时创建自定义形状。

Drawable List 状态集合

StateListDrawable是一个在XML中定义的可绘制对象,根据对象的状态,使用多个不同的图像来表示相同的图形。例如,Button控件可以以几种不同的状态之一存在(按下,有焦点或不可点击),并且使用Drawable的状态列表,可以为每个状态提供不同的背景图像。例如:android:state_pressed,android:state_focused,android:state_enabled,android:state_selected等等。下图显示了可以表示的所有主要状态:

例如,按钮背景的状态列表XML可能类似于以下文件中的内容:

现在,当视图(即按钮)被按下或聚焦时,用于视图的drawable将相应地改变。请注意,任何视图都有一个状态选择器,但最常见的用途是按钮和列表视图项目。也有颜色状态选择器,允许根据视图状态来选择颜色。

并应用于布局文件中按钮的textColor属性等颜色值的任何字段:

使用状态列表允许我们轻松定义响应按下,是否选中,是否可用或其他相关状态的动态视图。

创建 Layer List

一个LayerDrawable是一个drawable对象,管理其它的drawable数组。列表中的每个drawable都按照列表的顺序绘制 - 列表中的最后一个drawable绘制在顶部。每个drawable由单个元素内的元素表示。

LayerList可以用来绘制多个其它的drawable(形状,图像等),并将它们放置在相互之间的关系中。默认情况下,图层被放置在另一个的顶部,最后一个图层被绘制在顶部。然后可以使用left, right, top, and bottom属性来移动图层的坐标。

图层样式的常见用例包括: ① View边框阴影 ② View单边添加边框 ③ View分层背景 ④ View卡片背景 ⑤ 绘制三角形

举一个简单的例子,下面的图层列表绘制了几个相互关联的形状:

结果看起来像下面这样:

请记住,LayerList中的item也可以是图像或任何其他类型的drawable。你可以使用它来创建更复杂的drawable,并将多个drawable叠加在一起。在官方文档中查看更多示例。

可伸缩的 Nine-Patch Image

NinePatch是一个PNG图像,你可以在该图像中定义当View的内容超出正常图像边界时定义拉伸的可伸展区域。通常将此类型的图像作为View的背景,将其宽度设置为wrap_content。最常见的用法是一个Button,它必须根据里面显示的文字来拉伸。

NinePatch是具有.9.png文件扩展名的图像,表示这是一个可伸缩的PNG图像。该文件与正常的PNG文件没有什么不同,除了您将添加细黑线以指示图像的垂直和水平“可拉伸”和“填充”区域。Android不会显示这些guide lines(指导线),这些guide lines(指导线)用于确定如何呈现图像。 下面嵌入了一个9-patch image的例子(左边是9patch图形,右边是在应用程序中使用的一个例子):

NinePatch被定义并保存在drawable文件夹中,并将背景设置为与任何图像相同:

Android Studio可以直接编辑9-patch文件。你的PNG文件只需保存在drawable文件夹中以.9.png为扩展名,即可显示9-patch编辑器,而不是普通的图像编辑器。你可以使用鼠标来选择要拉伸的区域(使用Shift键并单击并拖动鼠标擦除区域),右侧的预览窗格将显示如何根据内部文本渲染图像。

需要为可拉伸区域定义左边和上边的线。为了避免在上面的例子中拉伸这个气泡的箭头,我们定义了这个区域之外的区域。右侧和底部的行定义了可以填充文本的位置。如果没有底线,您的文字将不会填满拉伸区域的整个宽度,并且可能无法正确居中。

有关更多信息,可以参考这个简单的操作指南。你也可以参考官方的文档。

Vector Drawables(矢量图)

这些XML是可绘制的,可以定义复杂的基于矢量的图像,可以自动缩放以支持所有的密度。这意味着使用基于矢量的图像,在位图图像的情况下,你只需要一个drawable file,而不是每个屏幕密度的drawable file。

首先,请参考设置指南以启用对pre-Lollipop devices(棒棒糖前设备)的矢量绘图支持。

创建 Vector Drawables

要创建一个矢量图像,您需要定义位于这里的pathData语法。本示例使用以下内容定义XML元素中的形状细节:

使用 Vector Drawables

然后,我们可以使用app:srcCompat属性来加载:

注意:请务必使用app:srcCompat来支持较旧的Android设备。如果你使用android:src作为vector drawable,你的应用可能会在较新的设备中正确呈现,但可能会在棒棒糖前设备中崩溃。 最终显示如下图所示:

你也可以在运行时使用代码来设置vector drawable:

ImageView iv = (ImageView) findViewById(...); iv.setImageResource(R.drawable.ic_heart);查找 Vector Drawables

现在可以在Android Studio中直接找到vector drawable,也可以在许多Android资源网站上找到。假设您已更新到Android Studio v2.2,您可以在File => New => Vector Asset向导中检查vector drawable:

您可以在material design icons website上找到其他图标,其中也包含社区贡献的图标。

转换为Vector Drawable

另外,有几种方法可以直接从SVG图形创建vector drawable: ① Vector Asset Studio - 是Android Studio中包含的一个实用工具(如上所示),用于将SVG asstes转换为vector drawable ② SVG2Android Online Utility - 直接在浏览器中将SVG转换为vector drawable ③ Command-line SVG Converter - 可以将SVG批量转换为vector drawable ④ Vectorizer - 将PNG图像转换为SVG以转换为vector drawable

自定义 Button

创建自定义按钮需要至少组合一个drawable的状态列表和一个drawable的形状。首先,我们来创建一个drawable的形状,res / drawable / nice_button_enabled.xml中的“默认”按钮背景:

我们还要创建一个style(视图属性集),其中包含在res / values / styles.xml中设置背景:

center_vertical|center_horizontal #FFFFFF @drawable/nice_button_enabled 16sp bold true true

这代表默认状态下按钮的形状和背景以及其他属性。我们可以通过设置按钮的style来应用这个:

结果会像下面这样:

现在Button很好地显示,但没有任何“按下”或“聚焦”的状态。要做到这一点,我们需要创建一个状态列表drawable来表示res / drawable / states_nice_button.xml中每个状态的drawable。

这描述了在所有三个主要状态(默认,按下和聚焦)中Button的外观。现在我们需要创建两个Shape drawable状态。一个用于res / drawable / nice_button_pressed.xml,另一个用于res / drawable / nice_button_focused.xml:

按压和聚焦的状态将显示相同,但​​这些也可能是不同的视觉状态。现在,我们需要改变style来使用res / drawable / states_nice_button.xml:

center_vertical|center_horizontal #FFFFFF @drawable/states_nice_button 16sp bold true true

现在我们有一个Button,它有一个很好的形状drawable背景,当按下时不需要单个图像资源就可以改变视觉状态!

自定义ListView

另一个常见需求是自定义ListView中项目的外观。首先让我们创建基本的ListView并在其中填充String项目。首先,res / layout / item_simple.xml中项目的布局XML:

接下来,让我们在一个activity中设置基本的ListView xml:

然后填充ListView:

ArrayList items = new ArrayList(); for (int i = 1; i < 8; i++) { items.add("Item " + i); } ArrayAdapter aItems = new ArrayAdapter(this, R.layout.item_simple, items); lvTest = (ListView) findViewById(R.id.lvTest); lvTest.setAdapter(aItems);

结果看起来像下面这样:

现在,让我们将自己的样式添加到ListView。让我们添加一个默认的渐变和一个按下的渐变,改变项目之间的分隔线颜色,并在ListView周围添加一个边框。首先,我们在res / drawable / gradient_bg.xml中为默认状态添加形状渐变背景:

然后在res / drawable / gradient_pressed_bg.xml中添加按下渐变背景:

然后让我们创建一个状态列表来描述在各种列表状态中使用的drawable:

接下来,我们通过设置“stroke”属性,在res / drawable / list_border.xml中使用一个Shape drawable设置ListView的边框:

现在让我们将这些XML drawable中的每一个应用于各种元素。首先,我们将背景添加到列表项本身并调整res / layout / item_simple.xml:

请注意,背景属性已设置为状态列表,以便为项目应用默认背景。接下来,让我们将边框和选择器状态添加到活动布局文件中的现有ListView:

在这里我们定制了divider color和dividerHeight以及背景来应用border和listSelector来管理一个item被按下时的状态。有了这一切,我们的自定义ListView现在看起来像:

我们现在已经成功地定制了我们的ListView的外观,并且它使用了一系列drawable。

运行时Drawables

我们可以通过访问具有可绘制应用的视图的背景,在我们的Java代码的运行时访问drawable。例如,给res / drawables / message_bubble.xml这个层列表:

然后我们可以从我们的activity中通过指定的id访问outerRectangle:

// Get drawable layer list from the background LayerDrawable bubble = (LayerDrawable) tvFoo.getBackground(); // Access GradientDrawable outerRect = (GradientDrawable) bubble.findDrawableByLayerId(R.id.outerRectangle); // Change the solid color of the drawable outerRect.setColor(Color.parseColor("#2f8f22"));

请注意,即使形状是纯色,此形状也是作为GradientDrawable访问的。

运行时Vector Drawables

如果你在运行时使用 vector drawables或animated vector drawables,请确保使用新的AppCompatResource类而不是普通的getDrawable()调用,特别是如果您在绘图中引用自定义主题属性(即?attr / colorAccent):

// Use AppCompatResource so that it will accurately use theme attributes Drawable drawable = AppCompatResources.getDrawable(R.drawable.ic_test_24dp); // Use this drawable ImageView imageView = (ImageView) findViewById(R.id.tst); imageView.setBackground(drawable);应用着色器

从Android 5.0及更高版本开始,现在可以将tint color应用于drawable。其优点是根据当前主题使用的图像风格。例如,在Twitter最近的Android UI更新中,大多数图像以黑色的形式存储为vector drawables:

这里是对应的vector drawable:

首先,我们将颜色添加到我们的colors.xml文件中:

#ff1da1f2 #ffaab8c2

将此vector drawable更改为蓝色的最简单方法是将android:tint属性应用于标记:

我们也可以动态改变这个:

ColorStateList colors; if (Build.VERSION.SDK_INT >= 23) { colors = getResources().getColorStateList(R.color.twitter_blue, getTheme()); } else { colors = getResources().getColorStateList(R.color.twitter_blue); } // Use for pre-Lollipop devices Drawable drawable = AppCompatResources.getDrawable(R.drawable.ic_test_24dp); // Wrap the drawable so that future tinting calls work on pre-v21 devices. Drawable icon = DrawableCompat.wrap(drawable); DrawableCompat.setTintList(icon, colors); }

注意,使用的着色颜色也可以使用可绘制的状态列表。例如,如果我们希望色彩根据图标是否被选中而改变颜色,我们可以创建一个res / color / tab_selector.xml:

额外的drawable类型

① LevelList - 一个Drawable,管理一些替代Drawables,每个分配一个最大数值。 ② TransitionDrawable - 可绘制的对象,可以在两个drawable资源之间交叉淡入淡出。用于两个drawable之间的动画。 ③ InsetDrawable - 在XML中定义的drawable表示将另一个drawable对象按指定的距离进行插入。当View需要比View的实际边界更小的背景时,这是非常有用的。 ④ ClipDrawable - 在XML中定义一个drawable,根据这个Drawable的当前级别剪切另一个drawable。最常用来实现诸如进度条之类的东西。 ⑤ ScaleDrawable - XML中定义的drawable根据当前级别更改另一个drawable的大小。

工具http://androiddrawables.com/http://angrytools.com/android/button/参考http://developer.android.com/guide/topics/resources/drawable-resource.htmlhttp://www.vogella.com/articles/AndroidDrawables/article.htmlhttp://developer.android.com/reference/android/graphics/drawable/Drawable.htmlhttp://android-dev-tips-and-tricks.blogspot.com/2012/08/xml-drawables-part-i.htmlhttp://androidcookbook.com/Recipe.seam;jsessionid=8BED36512503CA63614CA9237248CBE7?recipeId=3307http://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/


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3