Flutter资源管理插件r_resources的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter资源管理插件r_resources的使用

r_resources 是一个用于生成R文件代码的Flutter插件,通过 build_runner 实现。R文件提供了对应用程序资源名称的静态访问,并通过 BuildContext 继承访问本地化字符串资源。使用这种方法可以避免在资源名称中出现拼写错误。

如何使用

  1. 添加依赖项

    pubspec.yaml 文件中添加开发依赖项:

    dev_dependencies:
      build_runner: ^2.3.3  # 请根据需要选择版本
      r_resources: ^1.0.2
    
  2. 生成R文件

    运行以下命令以生成R文件:

    flutter pub run build_runner build
    

    生成的 r.dart 文件将位于 lib 文件夹中。

图片和SVG资源

为了为图片资源生成R名称,您需要按照以下步骤操作:

  1. 在项目根目录下创建 assets 文件夹(例如:your_app/assets)。

  2. 创建 images 文件夹用于存放普通图片文件(如 .png, .jpg 等)。也可以创建 svg 文件夹用于存放 .svg 文件。

  3. 将图片资源添加到这些文件夹中。

  4. pubspec.yaml 中添加 assets 配置:

    flutter:
      assets:
        - assets/images/
        - assets/svg/
    
  5. 运行代码生成命令。

注意:为了添加不同缩放因子的普通图片,可以在 images 文件夹内添加缩放文件夹,例如:

your_app:
  assets:
    images:
      2.0x:
        img.png
      3.0x:
        img.png
      img.png

生成 r.dart 文件后,您可以像下面这样引用资源:

Image.asset(R.images.ic_individual_schools);
SvgPicture.asset(R.svg.ic_filter);

配置文件

r_resources 提供了一些配置选项来控制代码生成。您可以在项目根目录下添加 r_options.yaml 配置文件。示例如下:

path: 'lib/codegen'  # 指定生成的 r.dart 文件保存路径,默认为 lib

generate_strings: true  # 是否生成字符串资源,默认为 false

supported_locales:
  - en_US
  - en_GB
  - ru  # 支持的语言和地区,默认为 en

fallback_locale: en_US  # 当缺少翻译时使用的默认语言和地区,默认为 en
  • path:指定 r.dart 文件保存的路径,路径必须以 lib 开头,默认为 lib
  • generate_strings:是否生成字符串资源,默认为 false,因为您可能使用其他本地化字符串生成包。
  • supported_locales:指定应用支持的语言和地区,默认为 en。仅当 generate_stringstrue 时有效。
  • fallback_locale:指定在缺少翻译时使用的默认语言和地区,默认为 en。仅当 generate_stringstrue 时有效。

字符串资源

r_resources 提供了一种简单的方法来生成应用的字符串翻译。默认情况下,字符串生成是关闭的。

如何使用字符串生成

要开始生成本地化字符串资源,您需要在配置文件中将 generate_strings 参数设置为 true,并配置 supported_localesfallback_locale 参数。

所有地区命名格式为 <language_code>_<country_code>,其中 country_code 可以省略以使用通用语言代码。例如:en_GBruen。注意 en_GBen 是不同的。

配置好 generate_stringssupported_localesfallback_locale 参数后,您需要将翻译文件添加到 your_app/assets/strings 目录下。

假设您在 r_options.yaml 中配置如下:

generate_strings: true

supported_locales:
  - en_US
  - en_GB
  - ru

fallback_locale: en_US

那么您需要添加 en_US.jsonen_GB.jsonru.json 文件。并且确保 en_US.json 文件包含所有可能的翻译,因为它将作为默认翻译。

翻译文件是单个JSON文件,不同翻译文件中的字段名称应保持一致。

例如,en_US.json(默认语言和地区):

{
    "label_lorem_ipsum": "Lorem ipsum",
    "label_color": "Color",
    "format_example": "Your object is ${object} and other is ${other}",
    "label_with_newline": "HELLO!\nI'm new line symbol (\\n)"
}

ru.json

{
    "label_color": "Цвет",
    "format_example": "Ты передал object = ${object}"
}

使用这些文件生成R后,您可以在代码中像下面这样访问本地化值:

Text(R.stringsOf(context).label_lorem_ipsum);
Text(R.stringsOf(context).label_color);

成功生成 r.dart 文件后,将会有两个新类:

  1. _Strings:可以通过 R.stringsOf(context) 访问,用作本地化值的容器。
  2. RStringsDelegateLocalizationsDelegate 类型为 _Strings 的代理。

您应该使用 RStringsDelegate 来配置应用的小部件本地化:

return MaterialApp(
  supportedLocales: RStringsDelegate.supportedLocales,
  localizationsDelegates: [
    RStringsDelegate(),
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  // 其他配置...
);
格式化

该插件还支持本地化格式化。例如,在 en_US.json(默认语言和地区)中:

{
    "format_example": "Your object is ${object} and other is ${other}"
}

ru.json 中:

{
    "format_example": "Ты передал object = ${object}"
}

这看起来像是JSON文件中的字符串插值。生成后,_Strings 类中将有一个函数而不是getter:

String format_example({
  required Object object,
  required Object other,
});

可以在代码中像下面这样使用:

Text(
  R.stringsOf(context).format_example(
    object: 12345,
    other: 'OTHER',
  ),
),

完整示例Demo

以下是一个完整的示例项目,展示了如何使用 r_resources 插件来管理资源和本地化字符串。

  1. 项目结构

    your_app/
    ├── assets/
    │   ├── images/
    │   │   └── ic_individual_schools.png
    │   ├── svg/
    │   │   └── ic_filter.svg
    │   └── strings/
    │       ├── en_US.json
    │       ├── en_GB.json
    │       └── ru.json
    ├── lib/
    │   └── main.dart
    ├── pubspec.yaml
    └── r_options.yaml
    
  2. pubspec.yaml

    name: your_app
    description: A new Flutter project.
    
    publish_to: 'none'  # Remove this line if you wish to publish to pub.dev
    
    version: 1.0.0+1
    
    environment:
      sdk: ">=2.17.0 <3.0.0"
    
    dependencies:
      flutter:
        sdk: flutter
      flutter_localizations:
        sdk: flutter
    
    dev_dependencies:
      build_runner: ^2.3.3
      r_resources: ^1.0.2
    
    flutter:
      assets:
        - assets/images/
        - assets/svg/
    
  3. r_options.yaml

    path: 'lib'
    
    generate_strings: true
    
    supported_locales:
      - en_US
      - en_GB
      - ru
    
    fallback_locale: en_US
    
  4. 翻译文件

    • assets/strings/en_US.json

      {
          "label_lorem_ipsum": "Lorem ipsum",
          "label_color": "Color",
          "format_example": "Your object is ${object} and other is ${other}",
          "label_with_newline": "HELLO!\nI'm new line symbol (\\n)"
      }
      
    • assets/strings/en_GB.json

      {
          "label_lorem_ipsum": "Lorem ipsum",
          "label_color": "Colour",
          "format_example": "Your object is ${object} and other is ${other}",
          "label_with_newline": "HELLO!\nI'm new line symbol (\\n)"
      }
      
    • assets/strings/ru.json

      {
          "label_lorem_ipsum": "Лорем ипсум",
          "label_color": "Цвет",
          "format_example": "Ты передал object = ${object}",
          "label_with_newline": "ПРИВЕТ!\nЯ новый символ переноса строки (\\n)"
      }
      
  5. main.dart

    import 'package:flutter/material.dart';
    import 'package:flutter_svg/flutter_svg.dart';
    import 'r.dart';  // 自动生成的 r.dart 文件
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          supportedLocales: RStringsDelegate.supportedLocales,
          localizationsDelegates: [
            RStringsDelegate(),
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            GlobalCupertinoLocalizations.delegate,
          ],
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(R.stringsOf(context).label_lorem_ipsum),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Image.asset(R.images.ic_individual_schools),
                SizedBox(height: 20),
                SvgPicture.asset(R.svg.ic_filter),
                SizedBox(height: 20),
                Text(R.stringsOf(context).label_color),
                SizedBox(height: 20),
                Text(
                  R.stringsOf(context).format_example(
                    object: 12345,
                    other: 'OTHER',
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
  6. 生成R文件

    在终端中运行以下命令以生成 r.dart 文件:

    flutter pub run build_runner build
    

    生成的 r.dart 文件将位于 lib 文件夹中。

  7. 运行应用

    使用以下命令运行应用:

    flutter run
    

更多关于Flutter资源管理插件r_resources的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter资源管理插件r_resources的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用r_resources插件进行资源管理的示例代码。r_resources插件允许你更方便地管理和访问应用程序的资源,如字符串、图片等。

首先,确保你的Flutter项目已经添加了r_resources插件。你可以在pubspec.yaml文件中添加以下依赖项:

dependencies:
  flutter:
    sdk: flutter
  r_resources: ^x.y.z  # 替换为实际的最新版本号

然后,运行flutter pub get来安装依赖项。

配置资源文件

在Flutter项目的res目录下(如果没有,可以手动创建),你可以组织你的资源文件。例如,创建一个strings目录来存放字符串资源文件:

res/
  ├── strings/
  │   └── en.json
  └── images/
      └── example.png

en.json文件内容示例:

{
  "welcome_message": "Welcome to our app!",
  "goodbye_message": "Goodbye!"
}

初始化RResources

在你的Flutter应用程序的入口文件(通常是main.dart)中,初始化RResources

import 'package:flutter/material.dart';
import 'package:r_resources/r_resources.dart';

void main() {
  // 初始化RResources,指定资源目录
  RResources.init(resourcePath: 'res');

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

使用RResources访问资源

在你的组件中,你可以使用RResources来访问资源文件中的内容。例如,在HomeScreen组件中:

import 'package:flutter/material.dart';
import 'package:r_resources/r_resources.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Resource Management'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              RResources.getString('welcome_message'),  // 从字符串资源文件中获取文本
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            Image.asset(
              'res/images/example.png',  // 直接从资源目录中获取图片
              width: 100,
              height: 100,
            ),
          ],
        ),
      ),
    );
  }
}

完整示例

以下是完整的示例代码,包括pubspec.yaml、资源文件和Dart代码:

pubspec.yaml

name: flutter_resource_management
description: A new Flutter project.

version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  r_resources: ^x.y.z  # 替换为实际的最新版本号

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
  assets:
    - res/images/example.png  # 如果你希望直接在pubspec中声明图片资源

res/strings/en.json

{
  "welcome_message": "Welcome to our app!",
  "goodbye_message": "Goodbye!"
}

res/images/example.png

(放置一张图片文件)

main.dart

import 'package:flutter/material.dart';
import 'package:r_resources/r_resources.dart';

void main() {
  RResources.init(resourcePath: 'res');
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Resource Management'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              RResources.getString('welcome_message'),
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            Image.asset(
              'res/images/example.png',
              width: 100,
              height: 100,
            ),
          ],
        ),
      ),
    );
  }
}

以上代码展示了如何在Flutter项目中使用r_resources插件进行资源管理,包括字符串和图片的访问。确保你按照实际使用的插件版本和资源结构进行调整。

回到顶部