前言
学习是一件持久的事,只有达到一定的量才能形成量变,程序员的学习也是如此
概述
资源是指在代码中使用的附加文件和静态内容,例如位图,布局定义,界面字符串,动画说明等。您应始终外部化应用资源(例如图像和代码中的字符串),以便单独对其进行维护。此外,您还应为特定设备配置提供备用资源,方法是将其进行分组并放入专门命名的资源目录中。在运行时,Android 会根据当前配置使用合适的资源。例如,您可能需根据屏幕尺寸提供不同的界面布局,或根据语言设置提供不同的字符串。
外部化应用资源后,您便可使用在项目 R 类中生成的资源 ID 来访问这些资源。本文档会介绍如何对 Android 项目中的资源进行分组,如何为特定的设备配置提供备用资源,以及如何从您的应用代码或其他 XML 文件访问这些资源。
资源分类
您应将各类资源放入到项目res/目录的特定目录中
下图是来自官网的一张截图,展示了res目录下可以什么类型的资源
提供备用资源
几乎每个应用都有备用资源,以便支持特定的设备配置,我下展示如何创建备用资源:
-
在res/中创建以 resource_name - config_qualifier形式命名的新目录
resource_name:是相应的默认资源的目录名称(如上图所示)。
qualifiter :是指定要使用这些资源的各个配置的名称(如表 2 中所定义)。
您可以追加多个 。以短划线将其分隔。 -
将相应的备用资源保存在此新目录下。这些资源文件必须与默认资源文件完全同名。
限定符命名规则
- 您可以为单组资源指定多个限定符,并使用短划线分隔。例如,drawable-en-rUS-land 适用于屏幕方向为横向的美国英语设备。
- 不能嵌套备用资源目录。例如,您的目录不能为 res/drawable/drawable-en/。
- 值不区分大小写。在处理之前,资源编译器会将目录名称转换为小写,以免不区分大小写的文件系统出现问题。名称中使用的所有大写字母只是为了便于认读。
- 每种限定符类型仅支持一个值。例如,若要对西班牙语和法语使用相同的可绘制对象文件,则您不能拥有名为 drawable-rES-rFR/ 的目录,而是需要两个包含相应文件的资源目录,如 drawable-rES/ 和 drawable-rFR/。然而,您实际无需在两处复制相同的文件。相反,您可以创建指向资源的别名。
创建别名资源
如果您想将某一个资源用于多种设备,则无需将同一个资源放入多个备用资源目录中。相反你可以创建备用资源,充当默认资源目录中所保存资源的别名
-
可绘制对象:如果要创建指向现有的可绘制对象,请使用 drawable 元素
- 将要使用的资源放在默认的drawable目录中.
- 在values下创建一个引用drawable中的图片的资源文件
- 在不同的使用的目录中引用在values中定义的drawable对象 -
布局:
- 如要创建指向现有布局的别名,请使用包装在 中的 元素
- 字符串和其他简单值,如要创建指向现有字符串的别名,您只需将所需字符串的资源 ID 用作新字符串的值
访问应用资源
在应用中提供资源后,您可通过引用其资源 ID 来应用该资源。所有资源 ID 都在您项目的 R 类中进行定义,该类由 aapt 工具自动生成。
编译应用时,aapt 会生成 R 类,其中包含 res/ 目录中所有资源的资源 ID。每个资源类型都有对应的 R 子类(例如,R.drawable 对应所有可绘制对象资源),而该类型的每个资源都有对应的静态整型数(例如,R.drawable.icon)。该整型数就是可用来检索资源的资源 ID。
资源ID的组成:
-
资源类型:每个资源都被分到一个“类型”组中,例如 string、drawable 和 layout。
-
资源名称:它是不包括扩展名的文件名;或是 XML android:name 属性中的值(如资源是字符串等简单值)。
-
资源的访问:在代码中使用
R.string.hello
在XML文件中@string/hello
在代码中访问资源:
你可以你参数的方式传入一个资源id,进而在代码中使用资源或者是利用 Resources 中的方法检索个别资源,并且您可通过 getResources() 获得该资源的实例。
语法:[<package_name>.]R.<resource_type>.<resource_name>
class MainActivity : AppCompatActivity() {
lateinit var imageView: ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
imageView = findViewById(R.id.imageviewid)
// 使用资源id的方式访问资源
imageView.setImageResource(R.drawable.ic_launcher_background)
//使用Resourece对象实现对资源的访问
imageView.setImageDrawable(resources.getDrawable(R.drawable.ic_launcher_background))
}
}
在XML中访问资源:
您可以使用对现有资源的引用,为某些 XML 属性和元素定义值。创建布局文件时,为给您的微件提供字符串和图像,您会经常这样做。
语法:@[<package_name>:]<resource_type>/<resource_name>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageviewid"/>
</LinearLayout>
引用样式属性:
利用样式属性资源,您可以在当前应用的主题背景中引用某个属性的值。借助引用样式属性,在自定义界面元素的外观时,您无需采用提供硬编码值这种方式,您可以通过为其设置样式,以匹配当前主题背景提供的标准变体来达成目的。引用样式属性的实质作用是,“在当前主题背景中使用此属性定义的样式”。
如要引用样式属性,名称语法几乎与普通资源格式完全相同,区别在于您需将 at 符号 (@) 改为问号 (?),并且资源类型部分为可选项。例如
语法:?[<package_name>:][<resource_type>/]<resource_name>
<EditText id="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:text="@string/hello_world" />
访问原始文件
尽管并不常见,但您的确有可能需要访问原始文件和目录。如果确有需要,则将文件保存在 res/ 中并没有用,因为从 res/ 读取资源的唯一方法是使用资源 ID。您可以改为将资源保存在 assets/ 目录中。
保存在 assets/ 目录中的文件没有资源 ID,因此您无法通过 R 类或在 XML 资源中引用它们。您可以改为采用类似普通文件系统的方式查询 assets/ 目录中的文件,并利用 AssetManager 读取原始数据。
不过,如果您只需要读取原始数据(例如视频文件或音频文件)的能力,则可将文件保存在 res/raw/ 目录中,并利用 openRawResource() 读取字节流。