参考:https://www.jianshu.com/p/4d3ae6d18993
一,应用资源概述
Android应用资源可分为两大类:
- 无法通过R资源清单类访问的原生资源,保存在assets目录下
- 可通过R资源清单类访问的资源,保存在res目录下
在Android应用中使用资源可分为在Java代码和XML文件中使用资源,其中Java代码用于为Android应用定义四大组件,而XML文件则用于为Android应用定义各种资源。
在Java代码中访问实际资源
可以借助于Android提供的Resources类来获取实际资源。Resources由Context调用getResources()方法来获取。Resources主要提供了如下两种方法:
getXxx(int id):根据资源清单ID来获取实际资源。
getAssets():获取访问/assets/目录下资源的AssetManager对象。
2,字符串、颜色、尺寸资源
字符串资源、颜色资源、尺寸资源,它们对应的XML文件都将位于/res/values/目录下,它们 默认的文件名以及在R类中对应的内部类如下所示
1.颜色值的定义
Android中的颜色值是通过红(Red)、绿(Green)、蓝(Blue)三原色以及一个透明度(Alpha)值来表示的,颜色值总是以#开头,接下来就是Alpha-Red-Green-Blue的形式。其中Alpha值可以省略,如果省略了Alpha值,name该颜色默认是完全不透明的。
Android颜色值支持常见的4种形式(A代表透明度,R代表红色数值,G代表绿色数值,B代表蓝色数值):
#RGB:分别指定红、绿、蓝三原色的值(0~F)来代表颜色。
#ARGB:分别指定红、绿、蓝三原色的值(0F)及透明度(0F)来代表颜色。
#RRGGBB:分别指定红、绿、蓝三原色的值(00~FF)来代表颜色。
#AARRGGBB:分别指定红、绿、蓝三原色的值(0F)及透明度(0F)来代表颜色。
2.定义字符串、颜色、尺寸资源文件
字符串资源文件位于/res/values/目录下,字符串资源文件的根元素是<resources…>,该元素里每个<string…/>子元素定义一个字符串常量,其中<string…/>元素的name属性指定该常量的名称,<string…/>元素开始标签和结束标签之间的内容代表字符串值。
<string name="hello">Hello World ,World!</string>
颜色资源文件位于/res/values/目录下,颜色资源文件的根元素是<resources…>,该元素里每个<color…/>子元素定义一个字符串常量,其中<color…/>元素的name属性指定该颜色的名称,<color…/>元素开始标签和结束标签之间的内容代表颜色值。
<color name="mycolor">#F00</color>
尺寸资源文件位于/res/values/目录下,尺寸资源文件的根元素是<resources…>,该元素里每个<dimen…/>子元素定义一个尺寸常量,其中<dimen…/>元素的name属性指定该尺寸的名称,<dimen…/>元素开始标签和结束标签之间的内容代表尺寸值。
<dimen name="mydimen">10dp</dimen>
二,数组资源
Android采用位于/res/values目录下的arrays.xml文件来定义数组资源,定义数组时XML资源文件的根元素也是<resources…/>,该元素内可包含如下三种子元素:
<array.../>子元素:定义普通类型的数组。
<string-array.../>子元素:定义字符串数组。
<integer-array.../>子元素:定义整型数组。
一旦定义好了数组资源之后,在Java程序中通过如下形式访问资源:
[<package_name>.]R.array.array_name
在XML文件中则可通过如下形式访问资源:
@[<package_name>:]array/array_name
为了能在Java程序中访问到实际数组,Resources提供了如下方法:
String[] getStringArray(int id):根据资源文件中字符串数组资源的名称来获取实际的字符串数组。
int[] getIntArray(int id):根据资源文件中整型数组资源的名称来获取实际的整型数组。
TypedArray obtainTypedArray(int id):根据资源文件中普通数组资源的名称来获取实际的普通数组。
三,图片资源
图片资源是最简单的Drawable资源,只要把.png、.jpg、*.gif等格式的图片放入/res/drawable-xxx目录下,AndroidSDK就会在编译应用中自动加载该图片,并在R资源清单类中生成该资源的索引。
一旦定义好了图片资源之后,在Java程序中通过如下形式访问资源:
[<package_name>.]R.drawable.<file_name>
在XML文件中则可通过如下形式访问资源:
@[<package_name>:]drawable/file_name
为了在程序中获得实际的Drawable对象,Resources提供了Drawable getDrawable(int id)方法,该方法即可根据Drawable资源在R资源清单类中的ID来获取实际的Drawable对象。
1.StateListDrawable资源
StateListDrawable用于组织多个Drawable对象。当使用StateListDrawable作为目标组件的背景、前景图片时,StateListDrawable对象所显示的Drawable对象会随目标组件状态的改变而自动切换。
定义StateListDrawable对象的XML文件的根元素为<selector…/>,该元素包含多个<item…/>元素,该元素可指定如下属性:
android:color或android:drawable:指定颜色或Drawable对象。
android:state_xxx:指定一个特定状态。
2.LayerDrawable资源
LayerDrawable也包含一个Drawable数组,所以系统会按这些Drawable对象的数组顺序来绘制它们,索引最大的Drawable对象将会被绘制在最上面。定义LayerDrawable对象的XML的根元素为<layer-list…/>,该元素可以包含多个<item…/>元素,该元素可指定如下属性:
android:drawable:指定作为LayerDrawable元素之一的Drawable对象。
android:id:为该Drawable对象指定一个标识。
android:buttom|top|left|button:用于指定一个长度值,用于指定将该Drawable对象绘制到目标组件的指定位置。
3.ShapeDrawable资源
ShapeDrawable用于定义一个基本的几何图形,定义它的XML文件的根元素是<shape…/>元素,该元素可指定如下属性:
android:shape=["rectangle"|"oval"|"line"|"ring"]:指定定义哪种类型的几何图形。
4.ClipDrawable资源
ClipDrawable代表从其他位图上截取的一个“图片片段”。在XML文件中定义ClipDrawable对象使用<clip…/>元素,可以指定如下三个属性:
android:drawable:指定截取的源Drawable对象。
android:clipOrientation:指定截取方向,可设置水平截取或垂直截取。
android:gravity:指定截取时的对齐方式。
在使用ClipDrawable对象时可以调用setLevel(int level)方法来设置截取的区域大小,当level为0时,截取的图片片段为空;当level为10000时,截取整张图片。
5.AnimationDrawable 资源
动画的相关知识还要另外做更详细的总结,所以这里只是简单的提一下。定义动画的XML资源应该放在/res/anmi/路径下,如果使用AndroidStudio创建一个Android应用的时候,默认不会包含该路径,我们需要自己创建该路径。
定义补间动画的XML资源文件以<set…/>元素作为根元素,该元素内可以指定下面几个元素:
alpha:设置透明度的改变。
scale:设置图片进行缩放变换。
translate:设置图片进行位移变换。
rotate:设置图片进行旋转。
Android 系统的R.anim类中包含了大量常量,它们定义了不同的动画速度:
linear_interpolator:匀速变换。
accelerate_interpolator:加速变换。
decelerate_interpolator:减速变换。
如果程序想让<set…/>元素下所有的变换效果使用相同的动画速度,则可以指定android:shareInterpolator="true"
为了在Java代码中获取实际的Animation对象,可调用AnimationUtils的如下方法:
oadAnimation(Context ctx ,int resId)
6.属性动画资源
Animator代表一个属性动画,但它只是一个抽象类。定义属性动画的XML资源文件能以下面三个元素中的任意一个作为根元素:
<set.../>:它是一个父元素,用于包含<objectAnimator.../>、<animator.../>或<set.../>子元素,该元素定义的资源代表AnimatorSet对象。
<objectAnimator.../>:用于定义ObjectAnimator动画。
<animator.../>:用于定义ValueAnimator动画。
四,使用原始XML资源
Android应用有一些初始化的配置信息、应用相关的数据资源需要保存,一般都是使用XML文件来保存的,这些资源被称为原始XML资源。
1.定义原始XML资源
原始XML资源一般保存在/res/xml/路径下–使用AndroidStudio创建Android应用时,/res/目录下并没有包含xml子目录,我们需要自行手动创建xml子目录。
定义好了原始XML资源,在XML文件中就可以通过如下语法格式来访问它:
@[<package_name>:]xml/file_name
在Java代码中则按如下语法来访问它:
[<package_name>.]R.xml.<file_name>
为了在Java程序中获取实际的XML文档,可以通过Resources的如下两个方法来实现:
XmlResourceParser getXml(int id):获取XML文档,并使用一个XmlPullParser来解析该XML文档,该方法返回一个解析器对象。
InputStream openRawResource(int id):获取XML文档对应的输入流。
2.使用原始XML文件
在程序中添加一个原始的XML文件,将该XML文件放到/res/xml目录下;
在Java程序中获取该XML资源,并解析该XML资源中的信息。
布局资源
布局资源(Layout)文件是放在/res/layout/目录下的,Layout资源文件的根元素通常是各种布局管理器,然后在布局管理器中定义各种View组件就可以了。
定义好Layout资源后,可通过如下语法来访问它:
@[<package_name>:]layout/file_name
在Java代码中可通过如下语法来访问它:
[<package_name>.]R.layout.<file_name>
菜单资源
菜单资源文件放在/res/menu/目录下,菜单资源的根元素通常是<menu…/>元素,<menu…/>元素无需指定任何属性。
定义好了菜单资源,接下来在XML文件中可以通过如下语法访问它:
@[<package_name>:]menu/file_name
在Java代码中可通过如下语法访问它:
[<package_name>.]R.menu.<file_name>
样式(Style)和主题(Theme)资源
样式资源文件放在/res/values/目录下,样式资源文件的根元素是<resources…/>元素,该元素包含多个<style…/>子元素,每个<style…/>子元素定义一个样式。<style…/>元素可以指定如下两个属性:
name:指定样式的名称。
parent:指定该样式所继承的父样式。当继承某个父样式时,该样式将会获得父样式中定义的全部格式。当然样式也可以覆盖父样式中指定的格式。
<style…/>元素内可包含多个<item…/>子元素,每个<item…/>子元素定义一个格式项。
定义好样式资源之后,在XML资源中可以通过如下语法访问它:
@[<package_name>:]style/file_name
主题资源的XML文件通常也放在/res/values/目录下,主题资源的XML文件同样以<resources…/>元素作为根元素,同样使用<style…/>元素来定义主题。
主题与样式的区别:
主题不能作用于单个的View组件,主题应该对整个应用中的所有Activity起作用,或对指定的Activity起作用。
主题定义的格式应该是改变窗口外观的格式,如窗口标题、窗口边框等。
Android5.0新增了Material设计得主题,我们只需要将APP的主题设为android:Theme.Material.Xxx即可启用Material主题。
Material Design支持包括下面几个方面:
- 系统自带Material Design主题;
- 允许通过View的setElevation()或setTranslationZ()方法让组件在屏幕上浮起来;
- 当用户点击按钮、复选框和其他可触碰组件时,将会自动显示水波动画;
- 具有Material设计风格的动画和Activity过渡效果。
属性资源(Attribute)
属性资源文件放在/res/values/目录下,属性资源文件的根元素也是<resources…/>元素,该元素包含如下两个子元素:
attr子元素:定义一个属性。
declare-styleable子元素:定义一个styleable对象,每个styleable对象就是一组attr属性的集合。
定义好属性资源文件后,可以在自定义组件的构造器中通过AttributeSet对象来获取这些属性。
使用原始资源
Android的原始资源可以放在如下两个地方:
- 位于/res/raw/目录下,AndroidSDK会处理这个目录下的原始资源,AndroidSDK会在R清单类中为这个目录下的资源生成一个索引项。
- 位于/assets/目录下,这个目录下的资源是更彻底的原始资源。需要通过AssetManager来管理这个目录下的原始资源
位于/res/raw/目录下的资源会在R清单类中生成一个索引项,在XML文件中可以通过下面的语法访问它:
@[<package_name>:]raw/file_name
在Java代码可以通过下面的语法访问它:
[<package_name>.]R.raw.<file_name>
AssetManager是一个专门管理/assets/目录下原始资源的管理器类,AssetManager提供了下面的方法来访问Assets资源:
InputStream open(String fileName):根据文件名来获取原始资源对应的输入流。
AssetFileDescripyor openFd(String fileName):根据文件名来获取原始资源对应的AssetFileDescripyor。
AssetFileDescripyor代表了一项原始资源的描述,应用程序可通过AssetFileDescripyor来获取原始资源。
国际化和资源自适应
引入国际化的目的是为了提供自适应、更友好的用户界面,并不需要改变程序的逻辑功能。国际化的英文单词是Internationalization,因为单词太长了,所以也称为I18N。
Java程序的国际化主要通过如下三个类完成:
java.util.ResourceBundle:用瑜伽在一个国家、语言资源包。
java.util.Locale:用于封装一个特定的国家/区域、语言环境。
java.text.MessageFormat:用于格式化带占位符的字符串。
为了实现程序的国际化,必须先提供程序所需要的资源文件。资源文件的命名可以有如下三种形式:
baseName_language_country.properties
baseName_language.properties
baseName.properties
其中baseName是资源文件的基本名,用户可以自由定义。但是language和country都不可以随意变化,必须是Java所支持的语言和国家。
1.Java支持的国家和语言
需要获取Java所支持的国家和语言,可以调用Locale类的getAvailableLocales方法获取,这个方法返回一个Locale数组,数组中包含了Java所支持的国家和语言。
Java程序国际化的关键类是ResourceBundle,它有个静态方法:getBundle(String baseName ,Locale locale)。这个方法会根据Locale加载资源文件,Locale封装了一个国家、语言。
2.位Android应用提供国际化资源
为了给/res/values/目录下的资源文件提供不同国家、语言的版本,不同的values文件夹的命名方式为:
values-语言代码-r 国家代码
不同的drawable文件夹的命名方式为:drawable-语言代码-r 国家代码
自适应不同屏幕的资源
Android设备的屏幕尺寸、分辨率差别非常大,但是又总希望可以在所有的Android设备上运行An冬日的应用,所以开发Android应用就需要考虑不同屏幕的适应性问题。
通常来说,屏幕资源需要考虑如下两个方面:
- 屏幕尺寸:屏幕尺寸可分为small、normal、large、xlarge四种;
- 屏幕分辨率:屏幕分辨率可分为ldpi、mdpi、hdpi、xhdpi、xxhdpi5种;
- 屏幕方向:屏幕方向可分为land和port两种。
四种屏幕尺寸所需的最低尺寸:
- xlarge屏幕尺寸至少需要960dp*720dp。
- large屏幕尺寸至少需要640dp*480dp。
- normal屏幕尺寸至少需要470dp*320dp。
- small屏幕尺寸至少需要426dp*320dp。
为了提供自适应不同屏幕的资源,最简单的做法就是为不同屏幕尺寸、不同屏幕分辨率提供相应的布局资源、Drawable资源:
- 屏幕分辨率:可以为drawable目录增加后缀ldpi、mdpi、hdpi、xhdpi,分别为不同分辨率的屏幕提供资源;
- 屏幕尺寸:可以为layout、values等目录增加后缀small、normal、large和xlarge,分别为不同尺寸的屏幕提供相应资源。
- 屏幕方向:可以为layout、values等目录增加后缀land和port,分别为横屏、竖屏提供相应的资源。