安卓权威编程指南-笔记(第21章 XML drawable)

在Andorid的世界里,凡事要在屏幕上绘制的东西都可以叫drawable,比如抽象图形,Drawable的子类,位图图形等,我们之前用来封装图片的BitmapDrawable就是一种drawable。

本章我们还会看到更多的drawable:state list drawable、shape drawable和layer list drawable。

这三个drawable都定义在XML文件中,可以归为一类,统称为XML drawable。

shape drawable

使用ShapeDrawable,可以把按钮编程圆形,XML drawable和屏幕像素密度无关,所以无需考虑创建特定像素密度目录,直接把它放入默认的drawable文件夹就可以了。

在res/drawable目录下创建一个圆形drawable。名为button_beat_box_normal.xml的文件,代码如下:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">

    <solid
        android:color="@color/drak_blue"/>

</shape>

该XML文件定义了一个背景色为深蓝色的圆形。 也可以使用shape drawable 定制其他图形。

最后修改styles中的按钮背景即可。

state list drawable

根据按钮的状态,state list drawable可以切换指向不同的drawable,它会根据按钮的状态改变使用的 drawable.

创建一个state list drawable

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_beat_box_pressed"
          android:state_pressed="true"/>
    <item android:drawable="@drawable/button_beat_box_normal"/>
</selector>

当按钮按下时用button_beat_box_pressed作为背景。没有按下时用button_beat_box_normal作背景。

除了按下状态,state list drawable还支持禁用,聚焦,以及激活等状态。

layer list drawable

layer list drawable能让两个XML drawable合二为一,借助这个工具可以为按下状态的按钮添加一个深色的圆环。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 3     <item>
 4         <shape xmlns:android="http://schemas.android.com/apk/res/android"
 5                android:shape="oval">
 6
 7             <solid
 8                 android:color="@color/red"/>
 9         </shape>
10     </item>
11
12     <item>
13         <shape
14             android:shape="oval">
15             <stroke
16                 android:width="4dp"
17                 android:color="@color/drak_red"/>
18         </shape>
19     </item>
20
21 </layer-list>

为什么要用XML drawable

XML Reader用起来方便灵活,不仅用法多样,还易于更新维护,搭配使用shape drawable和 layer list drawable可以做出复杂的背景图,连图像编辑器都省了,更改BeatBox应用的配色更是简单,直接修改XML drawable中的颜色就行了。

XML Reader独立于屏幕像素密度,它们直接定义在drawable目录中,不需要加屏幕密度资源修饰符,如果是普通图像,就需要准备多个版本,以适配不同屏幕像素密度的设备,而XML drawable只要定义一次,就能在任何设备的屏幕上表现出色。

使用9-patch图像

9-patch图像可以解决图像拉伸问题,9-patch图像是一种特别处理过的文件,让Android知道图像的哪些部分可以拉伸,哪些不可以。只要处理得当,就能确保背景图的边角与原始图像保持一致。为什么要叫作9-patch呢?9-patch图像分成3×3的网格,即由9部分或9 patch组成的网格。网格角落部分不会被缩放,边缘部分的4个patch只按一个维度缩放,而中间部分则按两个维度缩放,如图所示:

9-patch图像和普通PNG图像十分相似,只有两处不同:9-patch图像文件名以.9.png结尾,图像边缘具有1像素宽度的边框。这个边框用以指定9-patch图像的中间位置。边框像素绘制为黑线,以表明中间位置,边缘部分则用透明色表示。

 使用 Mipmap 图像

资源修饰符和drawable用起来都很方便。应用要用到图像,就针对不同的设备尺寸准备不同尺寸的图片,再分别放入drawable-mdpi和drawable-hdpi这样的文件夹。然后,按名字引用它们。剩下的就交给Android了,它会根据当前设备的屏幕密度调用相应的图片。

有个问题不得不提。发布到Google应用商店的APK文件包含了项目drawable目录里的所有图片,哪怕是从来不会用到的图片。这是个负担。

有人想到针对设备定制APK,比如mdpi APK一个,hdpi APK一个,等等。但问题解决得不够彻底。假如想保留各个屏幕像素密度的启动图标呢?

Android启动器是个常驻主屏幕的应用(详见第22章)。按下设备的主屏幕键,会回到启动器应用界面。有些新版启动器会显示大尺寸应用图标。想让大图标清晰好看,启动器就需要使用更高分辨率的图标。对于hdpi设备,要显示大图标,启动器就会使用xhdpi图标。找不到的话,就只能使用低分辨率的图标。可想而知,放大拉伸后的图标肯定很糟。Android的终极解决之道是使用mipmap目录。

APK分包时,mipmap资源会全部包含在APK文件中。要一劳永逸,推荐的做法就是,把应用启动器图标放在mipmap目录中,其他图片都放在drawable目录中。

时间: 2024-11-08 22:24:29

安卓权威编程指南-笔记(第21章 XML drawable)的相关文章

安卓权威编程指南-笔记(第26章 服务的作用)

1. IntentService IntentService也是一个context(Service是Context的子类),并能够响应intent. 一个最基本的IntentService实例如下: public class PollService extends IntentService { private static final String TAG = "PollService"; public static Intent newIntent(Context context)

安卓权威编程指南-笔记(第27章 broadcast intent)

本章需求:首先,让应用轮询新结果并在有所发现时及时通知用户,即使用户重启设备后还没有打开过应用.其次,保证用户在使用应用时不出现新结果通知. 1. 一般intent和broadcast intent 许多系统组件需要知道某些事件的发生(WIFI信号时有时无,电话的呼入等),为满足这样的需求,Andorid提供了broadcast intent 组件. broadcast intent的工作原理类似于之前学过的intent,但不同的是broadcast intent可以被多个叫做broadcast

安卓权威编程指南-笔记(第25章 搜索)

1. SearchView SearchView是个操作视图,所谓操作视图,就是可以内置在工具栏中的视图.SearchView可以让整个搜索界面完全内置在应用的工具栏中. 1.1 SearchView的配置 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:ap

安卓权威编程指南-笔记 (第29章定制视图与触摸事件)

1.定制视图 Android自带众多优秀的标准视图与组件,但有时为追求独特的应用视觉效果,我们仍需创建定制视图. 定制视图分为两大类别: 简单视图: 简单视图内部也可以很复杂,之所以归为简单类别,是因为简单视图不包括子视图,而且简单视图几乎总是会执行定制绘制. 聚合视图:聚合视图由其他视图对象组成,聚合视图通常管理着子视图,但不负责执行定制绘制,图形绘制任务都委托给了各个子视图. 创建定制视图的所需的三大步骤: 选择超类.对于简单定制视图而言,View是个空白画布,因此它作为超类最常见,对于聚合

安卓权威编程指南-笔记(第24章 Looper Handler 和 HandlerThread)

AsyncTask是执行后台线程的最简单方式,但它不适用于那些重复且长时间运行的任务. 1. Looper Android中,线程拥有一个消息队列(message queue),使用消息队列的线程叫做消息循环(message loop).消息循环会循环检查队列上是否有新消息. 消息循环由线程和looper组成,Looper对象管理着线程的消息队列. 主线程就是个消息循环,因此也拥有Looper,主线程的所有工作都是由其looper完成的,looper不断的从消息队列中抓去消息,然后完成消息指定的

安卓权威编程指南 挑战练习 22章 应用图标

本章使用了 ResolveInfo.loadLabel(...) 方法,在启动器应用中显示了各个activity的名 称. ResolveInfo 类还提供了另一个名为 loadIcon() 的方法.可以使用该方法为每个应用加载 显示图标.你要接受的挑战就是,为NerdLauncher应用中显示的所有应用添加对应的图标. 首先增加一个RecyclerView的条目布局,代码如下: 1 <?xml version="1.0" encoding="utf-8"?&

安卓权威编程指南 挑战练习 24章 预加载以及缓存

24.7 挑战练习:预加载以及缓存 应用中并非所有任务都能即时完成,对此,大多用户表示理解.不过,即使是这样,开发者们也一直在努力做到最好.为了让应用反应更快,大多数现实应用都通过以下两种方式增强自己的代码:? 增加缓存层 ? 预加载图片 缓存指存储一定数目 Bitmap 对象的地方.这样,即使不再使用这些对象,它们也依然存储在那里. 缓存的存储空间有限,因此,在缓存空间用完的情况下,需要某种策略对保存的对象做一定的取舍.许多缓存机制使用一种叫作LRU(least recently used,最

安卓权威编程指南 挑战练习 25章 深度优化 PhotoGallery 应用

你可能已经注意到了,提交搜索时, RecyclerView 要等好一会才能刷新显示搜索结果.请接受挑战,让搜索过程更流畅一些.用户一提交搜索,就隐藏软键盘,收起 SearchView 视图(回到只显示搜索按钮的初始状态).再来个挑战.用户一提交搜索,就初始化 RecyclerView ,显示一个搜索结果加载状态界面(使用状态指示器).下载到JSON数据之后,就删除状态指示器.也就是说,一旦开始下载图片, 就不应显示加载状态了 1.提交搜索,隐藏软键盘,收起SearchView: 将SearchV

安卓权威编程指南 - 第五章学习笔记(两个Activity)

学习安卓编程权威指南第五章的时候自己写了个简单的Demo来加深理解两个Activity互相传递数据的问题,然后将自己的学习笔记贴上来,如有错误还请指正. IntentActivityDemo学习笔记 题目:ActivityA登录界面(用户名.密码.登陆按钮),ActivityB(Edit,返回按键:SubmitButton).A界面输入用户名和密码传到B中,B验证用户输入的用户名和密码,如果错误就返回A,并用Toast 显示用户名和密码错误:如果正确,就在第二个 activity中显示一个Edi