Android | 资源类型详解

文章目录

  • [📘 Android 资源类型详解](#📘 Android 资源类型详解)
    • [3.1 🖼️ 图片资源(Drawable 和 Mipmap)](#3.1 🖼️ 图片资源(Drawable 和 Mipmap))
      • [3.1.1 🖼️ Drawable 资源(Drawable Resources)](#3.1.1 🖼️ Drawable 资源(Drawable Resources))
        • [📌 整体介绍](#📌 整体介绍)
        • [✅ 支持的格式及特点](#✅ 支持的格式及特点)
        • [🗂️ 存放位置](#🗂️ 存放位置)
        • [🔧 使用方式](#🔧 使用方式)
          • [(1)🖼️ 示例图:](#(1)🖼️ 示例图:)
    • 使用方式一
          • [(2)XML Drawable 类型详解](#(2)XML Drawable 类型详解)
            • 直接引用位图或矢量图
            • [① `<shape>`:定义几何形状](#① <shape>:定义几何形状)
            • [② `<selector>`:状态选择器](#② <selector>:状态选择器)
            • [③ `<layer-list>`:图层列表](#③ <layer-list>:图层列表)
            • [④ `<vector>`:矢量图形](#④ <vector>:矢量图形)
            • [⑤ `<level-list>`:等级列表](#⑤ <level-list>:等级列表)
            • [⑥ `<ripple>`:水波纹反馈](#⑥ <ripple>:水波纹反馈)
        • [📊 Drawable 类型总结表](#📊 Drawable 类型总结表)
      • [3.1.2 🖼️ Mipmap 资源(Mipmap Resources)](#3.1.2 🖼️ Mipmap 资源(Mipmap Resources))
        • [📌 整体介绍](#📌 整体介绍)
        • [✅ 优势](#✅ 优势)
        • [🗂️ 存放位置](#🗂️ 存放位置)
      • [3.1.3 🆚 对比:`drawable/` vs `mipmap/`](#3.1.3 🆚 对比:drawable/ vs mipmap/)
    • [3.2 📄 布局资源(Layout Resources)](#3.2 📄 布局资源(Layout Resources))
      • [3.2.1 📌 用途与位置](#3.2.1 📌 用途与位置)
      • [3.2.2 🔗 使用方式](#3.2.2 🔗 使用方式)
      • [3.2.3 🌐 限定符适配](#3.2.3 🌐 限定符适配)
      • [3.2.4 📊 布局类型对比](#3.2.4 📊 布局类型对比)
    • [3.3 值资源(Values/)](#3.3 值资源(Values/))
      • [3.3.1 🧾 字符串资源(`strings.xml`)](#3.3.1 🧾 字符串资源(strings.xml))
        • [📌 用途](#📌 用途)
        • [📁 位置](#📁 位置)
        • [📌 示例](#📌 示例)
        • [🔗 使用方式对比](#🔗 使用方式对比)
      • [3.3.2 🎨 颜色资源(`colors.xml`)](#3.3.2 🎨 颜色资源(colors.xml))
        • [📌 示例](#📌 示例)
        • [🔗 使用方式](#🔗 使用方式)
        • [📊 颜色格式](#📊 颜色格式)
      • [3.3.3 📏 尺寸资源(`dimens.xml`)](#3.3.3 📏 尺寸资源(dimens.xml))
        • [📌 示例](#📌 示例)
        • [🔗 使用方式](#🔗 使用方式)
        • [📊 尺寸单位说明](#📊 尺寸单位说明)
      • [3.3.4 🎭 样式主题资源(`styles.xml`)](#3.3.4 🎭 样式主题资源(styles.xml))
        • [📌 整体介绍](#📌 整体介绍)
        • [📁 位置](#📁 位置)
        • [📌 示例](#📌 示例)
        • [🔗 使用方式](#🔗 使用方式)
        • [🆚 样式 vs 主题](#🆚 样式 vs 主题)
        • [🔗 使用方式2](#🔗 使用方式2)
    • [3.4 📋 菜单资源(Menu)](#3.4 📋 菜单资源(Menu))
      • [📁 位置](#📁 位置)
      • [📌 示例](#📌 示例)
      • [🔗 使用方式](#🔗 使用方式)
      • [📊 菜单类型对比](#📊 菜单类型对比)
    • [3.5 🎞️ 动画资源(Animation Resources)](#3.5 🎞️ 动画资源(Animation Resources))
      • [📁 目录结构](#📁 目录结构)
      • [📊 动画类型对比](#📊 动画类型对比)
      • [3.5.3 补间动画示例(`res/anim/`)](#3.5.3 补间动画示例(res/anim/))
      • [3.5.4 属性动画示例(`res/animator/`)](#3.5.4 属性动画示例(res/animator/))
      • [3.5.5 🔗 使用方式](#3.5.5 🔗 使用方式)
    • [3.6 其他资源类型](#3.6 其他资源类型)
      • [3.6.1 📂 原始文件资源(Raw Resources)](#3.6.1 📂 原始文件资源(Raw Resources))
        • [🔗 使用方式](#🔗 使用方式)
      • [3.6.2 📄 XML 文件资源](#3.6.2 📄 XML 文件资源)
      • [3.6.3 🔤 字体资源](#3.6.3 🔤 字体资源)
      • [3.6.4 🗃️ Assets 资源](#3.6.4 🗃️ Assets 资源)
        • [🔗 使用方式](#🔗 使用方式)
        • [🆚 `raw` vs `assets`](#🆚 raw vs assets)
      • [3.6.5 🔢 数值资源(Integer, Bool, Array)](#3.6.5 🔢 数值资源(Integer, Bool, Array))
        • [🔗 使用方式](#🔗 使用方式)
        • [🆚 `raw` vs `assets`](#🆚 raw vs assets)
      • [3.6.5 🔢 数值资源(Integer, Bool, Array)](#3.6.5 🔢 数值资源(Integer, Bool, Array))
        • [🔗 使用方式](#🔗 使用方式)

📘 Android 资源类型详解

Android 应用中的资源(Resources)是指非代码部分的静态内容,如布局、字符串、图片、颜色、动画等。这些资源统一存放在 res/ 目录下,通过编译生成 R.java 类进行引用,支持多设备适配、国际化、主题切换等高级功能。

3.1 🖼️ 图片资源(Drawable 和 Mipmap)

3.1.1 🖼️ Drawable 资源(Drawable Resources)

📌 整体介绍

用于图像、背景、图标等视觉元素,支持位图(PNG/JPEG/WebP)、矢量图(VectorDrawable)、形状定义(Shape)、状态选择器(Selector)、图层叠加(Layer-list)等多种形式。

✅ 支持的格式及特点
格式 优点 缺点 特点 使用场景
PNG - 无损压缩 ,图像质量高 - 支持透明通道 (Alpha) - 兼容性极好 - 文件体积较大 (尤其对于照片类图像) - 不适合存储复杂渐变或照片 保留所有原始数据,边缘清晰 - 图标、按钮、Logo 等需要透明背景的 UI 元素 - 小尺寸、颜色简单 的图形 -
JPEG - 有损压缩文件体积小 - 适合存储照片和复杂色彩图像 - 不支持透明度、动画 - 压缩会导致细节损失(产生噪点,不适合文字/锐利边缘图形) 通过合并相邻像素的颜色信息来压缩(彩色图像编码方案) - 背景图、用户头像、商品图片 等照片类内容 - 对体积敏感无需透明 的场景 - 网络摄影作品 与生活照、色彩层次丰富的艺术画作
WebP - 同时支持有损 & 无损 压缩 - 支持透明通道、动图 - 比 PNG/JPEG 体积更小 (通常小 25%~35%) - 部分旧工具链兼容性差 采用预测编码等先进算法:有损时比 JPG 清晰,无损时比 PNG 小 - 现代 App 中替代 PNG/JPEG 的首选 - 需要兼顾体积与透明度的场景(如带透明的照片图标)
Vector (SVG/VectorDrawable) - 矢量格式 ,无限缩放不失真 - 对于简单图形,文件体积极小 - 一套资源 适配所有屏幕密度 - 灵活可控:可用代码编辑与交 - 不适合复杂图像 (如照片) - 复杂路径 的绘制可能增加内存/CPU 开销 - 渲染性能在首次/复杂场景下可能低于位图 - 有学习门槛:需要理解其代码结构 - 与分辨率无关 - 本质是结构化文档 - 多尺寸应用的图标、简单图形 - Material Design 图标 - 需要多分辨率适配 的静态图形 - 可进行路径变换的动画图形(需使用 AnimatedVectorDrawable) - 字体、插画 与平面设计素材 - 数据可视化图表与地图

💡 官方推荐 :优先使用 VectorDrawable 替代位图,减少 APK 体积并提升适配能力。

🗂️ 存放位置
复制代码
res/
├── drawable-mdpi/    # 中等密度 (~160dpi)
├── drawable-hdpi/    # 高密度 (~240dpi)
├── drawable-xhdpi/   # 超高密度 (~320dpi)
├── drawable-xxhdpi/  # 超超高密度 (~480dpi)
└── drawable-xxxhdpi/ # 超超超高密度 (~640dpi)

⚠️ 若使用 VectorDrawable,则只需一份 drawable/ 文件,无需多密度版本。


🔧 使用方式
(1)🖼️ 示例图:

(2)XML Drawable 类型详解
直接引用位图或矢量图
xml 复制代码
<!-- XML -->
<ImageView
    android:src="@drawable/ic_launcher"
    android:background="@drawable/rounded_rectangle" />

<Button
    android:background="@drawable/button_selector" />
java 复制代码
// Java
ImageView imageView = findViewById(R.id.image_view);
imageView.setImageResource(R.drawable.ic_launcher);
imageView.setBackgroundResource(R.drawable.rounded_rectangle);

Drawable drawable = ContextCompat.getDrawable(context, R.drawable.ic_launcher);
kotlin 复制代码
// Kotlin
val imageView: ImageView = findViewById(R.id.image_view)
imageView.setImageResource(R.drawable.ic_launcher)
imageView.background = ContextCompat.getDrawable(this, R.drawable.rounded_rectangle)
<shape>:定义几何形状

用途:创建矩形、椭圆、直线、圆环等,并可设置颜色、渐变、圆角、描边、内边距。

xml 复制代码
<!-- res/drawable/rounded_rectangle.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/primary_color" />
    <corners android:radius="@dimen/button_corner_radius" />
    <stroke android:width="1dp" android:color="@color/accent_color" />
    <padding
        android:left="8dp"
        android:top="4dp"
        android:right="8dp"
        android:bottom="4dp" />
</shape>

🖼️ 效果图:


<selector>:状态选择器

根据 View 状态(按下、聚焦、启用等)切换不同 Drawable,常用于按钮反馈。

xml 复制代码
<!-- res/drawable/button_selector.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_pressed" android:state_pressed="true" />
    <item android:drawable="@drawable/button_focused" android:state_focused="true" />
    <item android:drawable="@drawable/button_normal" />
</selector>
  • button_pressed.xml:按下时显示深蓝色
  • button_focused.xml:获得焦点时显示中蓝色
  • button_normal.xml:默认状态显示标准蓝色

🖼️ 动态效果:


<layer-list>:图层列表

将多个 Drawable 堆叠,实现复合效果(如图标+背景、阴影、光泽)。

xml 复制代码
<!-- res/drawable/layered_icon.xml -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval">
            <solid android:color="@color/primary_color" />
        </shape>
    </item>
    <item
        android:drawable="@drawable/ic_icon"
        android:gravity="center" />
</layer-list>

🖼️ 效果图:


<vector>:矢量图形

使用 SVG 路径语法定义可缩放图标,一套文件适配所有屏幕。

xml 复制代码
<!-- res/drawable/ic_arrow.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="@color/primary_color"
        android:pathData="M12,2L1,21h22L12,2z" />
</vector>

🖼️ 效果图:


<level-list>:等级列表

根据整数值(Level)切换 Drawable,适用于电量、信号强度、进度等场景。

xml 复制代码
<!-- res/drawable/battery_level.xml -->
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:maxLevel="10" android:drawable="@drawable/battery_low" />
    <item android:maxLevel="50" android:drawable="@drawable/battery_medium" />
    <item android:maxLevel="100" android:drawable="@drawable/battery_full" />
</level-list>

Java 使用示例:

java 复制代码
LevelListDrawable levelDrawable = (LevelListDrawable) getResources().getDrawable(R.drawable.battery_level, null);
levelDrawable.setLevel(75); // 设置为 75%
imageView.setImageDrawable(levelDrawable);

完整 Demo 代码:

java 复制代码
package com.itzy.myapplication;

import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.graphics.Color;
import android.graphics.drawable.LevelListDrawable;
import android.view.ViewGroup;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private LevelListDrawable levelDrawable;
    private TextView levelText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(LinearLayout.VERTICAL);
        mainLayout.setLayoutParams(new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT));

        levelDrawable = (LevelListDrawable) getResources().getDrawable(R.drawable.battery_level, null);
        levelDrawable.setLevel(75);
        mainLayout.setBackground(levelDrawable);

        TextView titleText = new TextView(this);
        titleText.setText("Level List Drawable Demo");
        titleText.setTextSize(24);
        titleText.setTextColor(Color.BLACK);
        titleText.setPadding(50, 50, 50, 50);

        levelText = new TextView(this);
        levelText.setText("Battery Level: 75%");
        levelText.setTextSize(20);
        levelText.setTextColor(Color.BLACK);
        levelText.setPadding(50, 50, 50, 50);

        SeekBar levelSeek = new SeekBar(this);
        levelSeek.setMax(100);
        levelSeek.setProgress(75);
        levelSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                levelDrawable.setLevel(progress);
                levelText.setText("Battery Level: " + progress + "%");
                mainLayout.invalidate();
            }
            @Override public void onStartTrackingTouch(SeekBar seekBar) {}
            @Override public void onStopTrackingTouch(SeekBar seekBar) {}
        });

        LinearLayout.LayoutParams seekParams = new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        seekParams.setMargins(50, 50, 50, 100);
        levelSeek.setLayoutParams(seekParams);

        mainLayout.addView(titleText);
        mainLayout.addView(levelText);
        mainLayout.addView(levelSeek);
        setContentView(mainLayout);
    }
}

🖼️ 动态演示:


<ripple>:水波纹反馈

提供 Material Design 风格的触摸涟漪效果。

xml 复制代码
<!-- res/drawable/ripple_bg.xml -->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
    <item android:drawable="@color/white" />
</ripple>

🖼️ 效果图:


📊 Drawable 类型总结表
种类 XML 标签 主要用途
BitmapDrawable <bitmap> 包装位图,设置平铺等
ShapeDrawable <shape> 创建纯色/渐变的几何形状
LayerDrawable <layer-list> 组合多个 Drawable 实现复杂效果
StateListDrawable <selector> 根据视图状态切换 Drawable
LevelListDrawable <level-list> 根据整数值等级切换 Drawable
VectorDrawable <vector> 创建可缩放的矢量图标
AnimatedVectorDrawable <animated-vector> 为矢量图添加动画
RippleDrawable <ripple> 提供 Material Design 水波纹反馈
ClipDrawable <clip> 裁剪 Drawable(用于进度条)

3.1.2 🖼️ Mipmap 资源(Mipmap Resources)

📌 整体介绍

专门用于存放应用启动图标(Launcher Icon)

✅ 优势
  • 系统在 launcher 界面会使用不同密度的 mipmap 资源,获得更好缩放效果
  • 即使 APK 分包(split by density),mipmap 资源也不会被移除,确保图标始终可用
🗂️ 存放位置
复制代码
res/mipmap-mdpi/
res/mipmap-hdpi/
res/mipmap-xhdpi/
res/mipmap-xxhdpi/
res/mipmap-xxxhdpi/

3.1.3 🆚 对比:drawable/ vs mipmap/

特性 drawable/ mipmap/
用途 通用图片资源 仅用于 launcher icon
密度分包优化 会被移除未用密度 不会被移除
缩放质量 一般 ✅ 更适合 launcher 缩放
官方建议 所有非图标资源 必须用于应用图标

Google 明确要求:应用图标必须放在 mipmap/


3.2 📄 布局资源(Layout Resources)

3.2.1 📌 用途与位置

  • 用途:定义 UI 界面结构,
  • 位置res/layout/
  • 文件类型.xml这些定义Ui界面的XML文件通常用于搭建程序的各个界面。

3.2.2 🔗 使用方式

xml 复制代码
<!-- activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
</LinearLayout>
kotlin 复制代码
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main) // 加载布局
        
        val textView = findViewById<TextView>(R.id.textView) // 通过ID获取视图
        textView.text = "Hello Android!"
    }
}

点击此处演示视频

3.2.3 🌐 限定符适配

  • layout-land/:横屏
  • layout-port/:竖屏
  • layout-sw600dp/:最小宽度 ≥600dp(7寸平板)
  • layout-sw720dp/:10寸平板
java 复制代码
Configuration config = getResources().getConfiguration();
Log.d("Config", "Orientation: " + config.orientation);
Log.d("Config", "Smallest width: " + config.smallestScreenWidthDp + "dp");

3.2.4 📊 布局类型对比

布局类型 特点 使用场景
LinearLayout 线性排列 简单列表、表单
RelativeLayout 相对位置 复杂布局(已逐步被 ConstraintLayout 取代)
ConstraintLayout 约束关系 现代复杂布局首选
FrameLayout 层叠布局 单个子视图或层叠(如 Fragment 容器)
GridLayout 网格布局 网格状排列
TableLayout 表格布局 表格数据展示

3.3 值资源(Values/)

3.3.1 🧾 字符串资源(strings.xml

📌 用途

集中管理文本,支持国际化、格式化、复数、HTML、数组,避免硬编码。。

📁 位置
复制代码
res/values/strings.xml       // 默认
res/values-en/strings.xml    // 英文
res/values-zh/strings.xml    // 中文
📌 示例
xml 复制代码
<resources>
    <!-- 普通字符串 -->
    <string name="app_name">我的应用</string>
    <string name="welcome_message">欢迎使用</string>
    
    <!-- 带参数的格式化字符串 -->
    <string name="greeting">你好, %1$s! 你有 %2$d 条新消息</string>
    
    <!-- HTML 格式字符串 -->
    <string name="html_text"><![CDATA[欢迎来到<b>我的应用</b><br/>这是<u>下划线文本</u>]]></string>
    
    <!-- 复数形式 -->
    <plurals name="item_count">
        <item quantity="one">%d 个项目</item>
        <item quantity="other">%d 个项目</item>
    </plurals>
    
    <!-- 字符串数组 -->
    <string-array name="fruits">
        <item>苹果</item>
        <item>香蕉</item>
        <item>橙子</item>
    </string-array>
</resources>
🔗 使用方式对比
  • 在布局中

    xml 复制代码
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
  • 在代码中

    kotlin 复制代码
    val text = getString(R.string.hello_world)
    val formattedText = getString(R.string.welcome_message, "张三", 5)
使用场景 XML 中使用 Java 中使用 Kotlin 中使用
普通字符串 @string/app_name getString(R.string.app_name) 同左
格式化字符串 不支持 getString(R.string.greeting, "John", 5) 同左
HTML 字符串 不支持 Html.fromHtml(getString(R.string.html_text)) 同左
复数形式 不支持 getResources().getQuantityString(R.plurals.item_count, count, count) resources.getQuantityString(...)
字符串数组 不支持 getResources().getStringArray(R.array.fruits) resources.getStringArray(...)

🖼️ 国际化切换演示: "切换系统语言"

xml 复制代码
<!-- values/strings.xml -->
<resources>
    <string name="app_name">我的应用</string>
    <string name="hello_world">你好,世界!</string>
    <string name="welcome_message">欢迎,%1$s!你有%2$d条新消息。</string>
</resources>

<!-- values-en/strings.xml (英文翻译) -->
<resources>
    <string name="app_name">My Application</string>
    <string name="hello_world">Hello World!</string>
    <string name="welcome_message">Welcome, %1$s! You have %2$d new messages.</string>
</resources>

演示视频

3.3.2 🎨 颜色资源(colors.xml

统一管理颜色值,支持十六进制、ARGB、状态选择器(如按钮按下变色)。

📌 示例
xml 复制代码
<!-- values/colors.xml -->
<resources>
    <color name="color_primary">#3F51B5</color>
    <color name="color_primary_dark">#303F9F</color>
    <color name="color_accent">#FF4081</color>
    <color name="text_color">#212121</color>
</resources>

<!-- values-night/colors.xml (深色主题) -->
<resources>
    <color name="color_primary">#1A237E</color>
    <color name="text_color">#FFFFFF</color>
</resources>
🔗 使用方式
xml 复制代码
<TextView android:textColor="@color/text_color" />
java 复制代码
// Java 中使用
int primaryColor = ContextCompat.getColor(context, R.color.primary_color);
view.setBackgroundColor(primaryColor);
kotlin 复制代码
// Kotlin 中使用
val primaryColor = ContextCompat.getColor(this, R.color.primary_color)
val accentColor = getColor(R.color.accent_color) // API 23+
📊 颜色格式
格式 示例 说明
#RGB #F00 红绿蓝,各1位
#ARGB #8F00 透明度+红绿蓝,各1位
#RRGGBB #FF0000 红绿蓝,各2位
#AARRGGBB #80FF0000 透明度+红绿蓝,各2位

3.3.3 📏 尺寸资源(dimens.xml

定义 UI 中的尺寸(如 padding、textSize),便于统一维护和适配。

📌 示例
xml 复制代码
<!-- values/dimens.xml -->
<resources>
    <dimen name="padding_small">8dp</dimen>
    <dimen name="padding_medium">16dp</dimen>
    <dimen name="text_size_large">18sp</dimen>
    <dimen name="button_corner_radius">4dp</dimen>
</resources>

<!-- values-sw600dp/dimens.xml (平板) -->
<resources>
    <dimen name="padding_medium">24dp</dimen>
    <dimen name="text_size_large">22sp</dimen>
</resources>
🔗 使用方式
xml 复制代码
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="@dimen/text_size_large"
    android:padding="@dimen/padding_medium" />
java 复制代码
// Java 中使用
float textSize = getResources().getDimension(R.dimen.text_size_medium);
int padding = getResources().getDimensionPixelSize(R.dimen.padding_medium);
kotlin 复制代码
// Kotlin 中使用
val textSize = resources.getDimension(R.dimen.text_size_medium)
val padding = resources.getDimensionPixelSize(R.dimen.padding_medium)
📊 尺寸单位说明
单位 描述 使用场景
dp 密度无关像素 布局尺寸、边距、填充
sp 缩放无关像素 文字大小(随系统字体缩放)
px 物理像素 不推荐
pt 点 (1/72英寸) 印刷品相关
mm 毫米 精确物理尺寸
in 英寸 精确物理尺寸
  • dp(Density-independent Pixels)密度无关像素
    • 描述:这是一种虚拟像素单位,主要用于Android开发中,它根据屏幕密度自动调整实际物理像素的数量。一个dp在160 dpi的屏幕上等于一个物理像素(px)。
    • 使用场景:布局尺寸、边距、填充等,用于确保应用界面在不同分辨率和屏幕尺寸的设备上都能保持一致的视觉效果。
  • sp(Scale-independent Pixels)缩放无关像素
    • 描述:类似于dp,但是还会根据用户的字体大小偏好进行缩放。这是为了适应用户可能设置的更大或更小的文字显示需求。
    • 使用场景:专门用于文字大小设定,以确保文本内容能够根据用户的偏好适当地缩放。
  • px(Pixels)物理像素
    • 描述:表示屏幕上的实际物理像素点。由于不同设备的屏幕密度差异很大,直接使用px作为单位会导致在不同设备上显示的效果不一致。
    • 使用场景:通常不推荐使用px来定义UI元素的尺寸,除非是在特定情况下需要固定物理像素的情况。
  • pt(Points)点 (1/72英寸)
    • 描述:传统印刷业使用的单位,1点等于1/72英寸。尽管在数字屏幕设计中不如dp或sp常用,但在某些涉及打印输出的设计时仍然是重要的单位。
    • 使用场景:与印刷品相关的设计工作,如创建PDF文档或设计将被打印出来的材料。
  • mm(Millimeters)毫米
    • 描述:国际单位制中的长度单位,1毫米等于千分之一米。这种单位提供了一种精确的物理尺寸测量方法。
    • 使用场景:当你需要基于具体的物理尺寸来设计时使用,例如在制造需要严格尺寸控制的产品原型时。
  • in(Inches)英寸
    • 描述:另一种常用的物理长度单位,在很多国家用于日常测量。1英寸等于25.4毫米。
    • 使用场景:同样适用于需要精确物理尺寸的应用场合,特别是在那些同时使用英制单位的项目中。

3.3.4 🎭 样式主题资源(styles.xml

📌 整体介绍
  • Style:应用于单个 View 的属性集合
  • Theme:应用于整个 Activity 或 App 的 Style,可继承
📁 位置
复制代码
res/values/styles.xml
res/values/themes.xml
📌 示例
  • View 属性(textColor, background 等)
  • 主题属性(colorPrimary, windowBackground 等)
xml 复制代码
<!-- values/styles.xml -->
<resources>
    <!-- 应用主题 -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <item name="colorPrimary">@color/color_primary</item>
        <item name="colorPrimaryDark">@color/color_primary_dark</item>
        <item name="colorAccent">@color/color_accent</item>
    </style>
    
    <!-- 自定义控件样式 -->
    <style name="PrimaryButton" parent="Widget.MaterialComponents.Button">
        <item name="android:textColor">@android:color/white</item>
        <item name="backgroundTint">@color/color_primary</item>
        <item name="cornerRadius">@dimen/button_corner_radius</item>
    </style>
</resources>
🔗 使用方式
xml 复制代码
<!-- 应用主题 AndroidManifest.xml  -->
<application
    android:theme="@style/AppTheme">
    
<!-- Activity 中应用样式 -->
<Button
    style="@style/PrimaryButton"
    android:text="确认" />

<!-- TextView 应用文本样式 -->
<TextView
    style="@style/HeadingText"
    android:text="标题" />
java 复制代码
// Java、Kotlin 中设置主题
setTheme(R.style.AppTheme);
🆚 样式 vs 主题
特性 样式 (Style) 主题 (Theme)
作用范围 单个 View 整个 Activity/Application
继承方式 parent 属性 parent 属性
应用方式 style 属性 android:theme 属性
常用场景 按钮样式、文本样式 应用整体外观
🔗 使用方式2
xml 复制代码
<!-- res/values/styles.xml -->
<resources>
    <!-- 基础主题 -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowBackground">@color/window_background</item>
    </style>
    
    <!-- 控件样式 -->
    <style name="PrimaryButton" parent="Widget.AppCompat.Button">
        <item name="android:background">@drawable/button_primary</item>
        <item name="android:textColor">@android:color/white</item>
        <item name="android:textSize">@dimen/text_size_medium</item>
        <item name="android:padding">@dimen/padding_medium</item>
    </style>
    
    <!-- 文本样式 -->
    <style name="HeadingText">
        <item name="android:textSize">20sp</item>
        <item name="android:textStyle">bold</item>
        <item name="android:textColor">@color/primary_color</item>
    </style>
    
    <!-- 对话框主题 -->
    <style name="CustomDialog" parent="Theme.AppCompat.Light.Dialog">
        <item name="colorAccent">@color/accent_color</item>
    </style>
</resources>

3.4 📋 菜单资源(Menu)

用于定义应用栏、上下文菜单和弹出菜单。

  • 使用: 在 Activity/Fragment 中,重写 onCreateOptionsMenu 并 inflate: menuInflater.inflate(R.menu.main_menu, menu)
  • 元素: <menu>, <item>, <group>

📁 位置

复制代码
res/menu/

📌 示例

xml 复制代码
<!-- res/menu/main_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    
    <!-- 普通菜单项 -->
    <item
        android:id="@+id/action_settings"
        android:icon="@drawable/ic_settings"
        android:title="@string/action_settings"
        app:showAsAction="ifRoom" />
    
    <!-- 带子菜单的项 -->
    <item
        android:id="@+id/action_more"
        android:title="@string/action_more"
        app:showAsAction="always">
        <menu>
            <item
                android:id="@+id/action_help"
                android:title="@string/action_help" />
            <item
                android:id="@+id/action_about"
                android:title="@string/action_about" />
        </menu>
    </item>
    
    <!-- 复选框菜单项 -->
    <item
        android:id="@+id/action_toggle"
        android:title="@string/action_toggle"
        android:checkable="true" />
    
</menu>

🔗 使用方式

Java
java 复制代码
// Java 中创建选项菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_settings:
            // 处理设置操作
            return true;
        case R.id.action_help:
            // 处理帮助操作
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
Kotlin
kotlin 复制代码
// Kotlin 中创建选项菜单
override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.main_menu, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.action_settings -> {
            // 处理设置操作
            true
        }
        R.id.action_help -> {
            // 处理帮助操作
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

📊 菜单类型对比

菜单类型 显示位置 创建方式 适用场景
OptionsMenu ActionBar onCreateOptionsMenu() 主要操作
ContextMenu 长按视图 registerForContextMenu() 上下文操作
PopupMenu 任意位置 PopupMenu 临时操作

3.5 🎞️ 动画资源(Animation Resources)

📁 目录结构

复制代码
res/
├── anim/      # 补间动画(Tween)
└── animator/  # 属性动画(Property)

📊 动画类型对比

动画类型 目录 特点 适用场景
补间动画 anim/ 视图动画、性能好 简单变换(淡入、滑动)
属性动画 animator/ 真实属性变化、更灵活 复杂动画、交互动画

3.5.3 补间动画示例(res/anim/

xml 复制代码
<!-- res/anim/fade_in.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">
    
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:duration="1000" />
        
    <scale
        android:fromXScale="0.5"
        android:toXScale="1.0"
        android:fromYScale="0.5"
        android:toYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="1000" />
        
</set>

<!-- res/anim/slide_in_left.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="-100%"
        android:toXDelta="0"
        android:duration="500" />
</set>

3.5.4 属性动画示例(res/animator/

xml 复制代码
<!-- res/animator/scale_animator.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="scaleX"
        android:duration="1000"
        android:valueFrom="1.0"
        android:valueTo="1.5" />
    <objectAnimator
        android:propertyName="scaleY"
        android:duration="1000"
        android:valueFrom="1.0"
        android:valueTo="1.5" />
</set>

3.5.5 🔗 使用方式

Java
java 复制代码
// Java 中使用补间动画
Animation fadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in);
view.startAnimation(fadeIn);

// Java 中使用属性动画
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.scale_animator);
set.setTarget(view);
set.start();
Kotlin
kotlin 复制代码
// Kotlin 中使用补间动画
val fadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in)
view.startAnimation(fadeIn)

// Kotlin 中使用属性动画
val set = AnimatorInflater.loadAnimator(this, R.animator.scale_animator) as AnimatorSet
set.setTarget(view)
set.start()

3.6 其他资源类型

3.6.1 📂 原始文件资源(Raw Resources)

存放原始文件(如音频、配置),编译时不处理,保持原样。

  • 位置res/raw/
  • ✅ 能存储.mp3, .json, .txt 等任意文件
  • 限制:不能有子目录;文件名需符合命名规则
🔗 使用方式
java 复制代码
// 存储位置: res/raw/
// 使用方式:
InputStream inputStream = getResources().openRawResource(R.raw.data_file);
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.sound_effect);

3.6.2 📄 XML 文件资源

  • 位置res/xml/
  • 用途:自定义配置(如 PreferenceScreen)
java 复制代码
// 存储位置: res/xml/
// 使用方式:
XmlResourceParser parser = getResources().getXml(R.xml.config);

3.6.3 🔤 字体资源

  • 位置res/font/
  • 格式.ttf, .otf
  • 字体族: 可以在 res/font/ 下创建一个 XML 文件,定义字体的不同风格(正常、粗体、斜体)及其对应的字体文件,系统会自动选择。
使用方式
xml 复制代码
<TextView android:fontFamily="@font/my_font" />
java 复制代码
Typeface typeface = ResourcesCompat.getFont(this, R.font.roboto_regular);
textView.setTypeface(typeface);
复制代码
// 使用方式:
TextView textView = findViewById(R.id.text_view);
Typeface typeface = ResourcesCompat.getFont(this, R.font.roboto_regular);
textView.setTypeface(typeface);
字体族定义
xml 复制代码
<!-- res/font/roboto.xml -->
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/roboto_regular" />
    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/roboto_italic" />
</font-family>

3.6.4 🗃️ Assets 资源

  • 位置assets/不在 res/
  • 特点:支持子目录;不生成 R.id
🔗 使用方式
java 复制代码
InputStream is = getAssets().open("data/config.json");
String[] files = getAssets().list("");
kotlin 复制代码
val is = assets.open("data/config.json")
val files = assets.list("")
🆚 raw vs assets
特性 res/raw/ assets/
生成 R.id
子目录支持
编译检查 ❌(运行时报错)
适用场景 简单固定资源 复杂资源包(游戏、HTML)

3.6.5 🔢 数值资源(Integer, Bool, Array)

  • 存储常量数值、开关标志、数组,便于配置管理。

  • 位置

    • res/values/integers.xml
    • res/values/bools.xml
🔗 使用方式
Java
java 复制代码
int max = getResources().getInteger(R.integer.max_retry);
boolean debug = getResources().getBoolean(R.bool.is_debug);
int[] primes = getResources().getIntArray(R.array.prime_numbers);
Kotlin
kotlin 复制代码
val max = resources.getInteger(R.integer.max_retry)
val debug = resources.getBoolean(R.bool.is_debug)
val primes = resources.getIntArray(R.array.prime_numbers)

ets().list("");

复制代码
```kotlin
val is = assets.open("data/config.json")
val files = assets.list("")
🆚 raw vs assets
特性 res/raw/ assets/
生成 R.id
子目录支持
编译检查 ❌(运行时报错)
适用场景 简单固定资源 复杂资源包(游戏、HTML)

3.6.5 🔢 数值资源(Integer, Bool, Array)

  • 存储常量数值、开关标志、数组,便于配置管理。

  • 位置

    • res/values/integers.xml
    • res/values/bools.xml
🔗 使用方式
Java
java 复制代码
int max = getResources().getInteger(R.integer.max_retry);
boolean debug = getResources().getBoolean(R.bool.is_debug);
int[] primes = getResources().getIntArray(R.array.prime_numbers);
Kotlin
kotlin 复制代码
val max = resources.getInteger(R.integer.max_retry)
val debug = resources.getBoolean(R.bool.is_debug)
val primes = resources.getIntArray(R.array.prime_numbers)
相关推荐
阿巴斯甜12 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker12 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952713 小时前
Andorid Google 登录接入文档
android
黄林晴14 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android