两分钟带你快速掌握Flutter的项目结构、资源、依赖和本地化

Posted by CrazyCodeBoy的技术博客官网 on April 2, 2019

flutter-project-structure-resources-dependencies-and-localization

为大家倾力打造的课程《Flutter从入门到进阶-实战携程网App》上线了,解锁Flutter开发新姿势,一网打尽Flutter核心技术 点我Get!!!

在这篇文章中,将带着大家一起认识Flutter的项目文件结构是怎样子的?在哪里归档图片资源以及如何处理不同分辨率?如何归档strings资源,以及如何处理不同语言?也就是我们通常说的国际化,以及如何添加Flutter项目所需的依赖?

首先我们来学习Flutter的项目文件结构是怎样子的?

项目文件结构是怎样子的?

一个Flutter项目的通常文件结构是这样子的:


 projectname
  
   android      - Android部分的工程文件
   build        - 项目的构建输出目录
   ios          - iOS部分的工程文件
   lib          - 项目中的Dart源文件
    
     src        - 包含其他源文件
     main.dart  - 自动生成的项目入口文件,类似RNindex.js文件
   test         - 测试相关文件
   pubspec.yaml - 项目依赖配置文件类似于RN package.json

当然大家也可以根据需要进行调整。

在哪里归档图片资源以及如何处理不同分辨率?

  • 虽然Android将resources 和 assets 区别对待,但在Flutter中它们都会被作为assets处理, 所有存在于Android上res / drawable- *文件夹中的资源都放在Flutter的assets文件夹中。
  • 与Android类似,iOS 同样将 images 和 assets 作为不同的东西,而 Flutter 中只有 assets。被放到 iOS 中 Images.xcasset 文件夹下的资源在 Flutter 中被放到了 assets 文件夹中。

在Flutter中assets 可以是任意类型的文件,而不仅仅是图片。例如,你可以把 json 文件放置到 my-assets 文件夹中。

my-assets/data.json

记得在 pubspec.yaml 文件中声明 assets

assets:
 - my-assets/data.json

然后在代码中我们可以通过 AssetBundle 来访问它:

import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;

Future<String> loadAsset() async {
  return await rootBundle.loadString('my-assets/data.json');
}

以上代码片段的完整部分可以在课程源码中查找。

对于图片,Flutter 像 iOS 一样,遵循了一个简单的基于像素密度的格式。Image assets 可能是 1.0x 2.0x 3.0x 或是其他的任何倍数。这个 devicePixelRatio 表示了物理像素到单个逻辑像素的比率。

Android不同像素密度的图片和Flutter的像素比率的对应关系

ldpi	0.75x
mdpi	1.0x
hdpi	1.5x
xhdpi	2.0x
xxhdpi	3.0x
xxxhdpi	4.0x

以上代码片段的完整部分可以在课程源码中查找。

Assets 可以被放置到任何属性文件夹中——Flutter 并没有预先定义的文件结构。我们需要在 pubspec.yaml 文件中声明 assets 的位置,然后 Flutter 会把他们识别出来。

举个例子,要把一个名为 my_icon.png 的图片放到 Flutter 工程中,你可能想要把它放到images文件夹中。把图片(1.0x)放置到 images 文件夹中,并把其它分辨率的图片放在对应的子文件夹中,并接上合适的比例系数,就像这样:

images/my_icon.png       // Base: 1.0x image
images/2.0x/my_icon.png  // 2.0x image
images/3.0x/my_icon.png  // 3.0x image

接下来就可以在pubspec.yaml文件中这样声明这个图片资源:

assets:
 - images/my_icon.png

现在,我们就可以借助AssetImage来访问它了。

return AssetImage("images/a_dot_burr.jpeg");

以上代码片段的完整部分可以在课程源码中查找。

也可通过 Image widget 直接使用:

@override
Widget build(BuildContext context) {
  return Image.asset("images/my_image.png");
}

更多内容,可参考在Flutter中添加assets 和 images

如何归档strings资源,以及如何处理不同语言?

不像 iOS 拥有一个 Localizable.strings 文件,Flutter目前没有专门的字符串资源系统。 目前,最佳做法是将strings资源作为静态字段保存在类中。 例如:

class Strings {
  static String welcomeMessage = "Welcome To Flutter";
}

然后像如下方式来访问它:

Text(Strings.welcomeMessage)

以上代码片段的完整部分可以在课程源码中查找。

默认情况下,Flutter 只支持美式英语字符串。如果你要支持其他语言,请引入 flutter_localizations 包。你可能也要引入 intl 包来支持其他的 i10n 机制,比如日期/时间格式化。

dependencies:
  # ...
  flutter_localizations:
    sdk: flutter
  intl: "^0.15.6"

以上代码片段的完整部分可以在课程源码中查找。

要使用 flutter_localizations 包,还需要在 app widget 中指定 localizationsDelegatessupportedLocales

import 'package:flutter_localizations/flutter_localizations.dart';

MaterialApp(
 localizationsDelegates: [
   // Add app-specific localization delegate[s] here
   GlobalMaterialLocalizations.delegate,
   GlobalWidgetsLocalizations.delegate,
 ],
 supportedLocales: [
    const Locale('en', 'US'), // English
    const Locale('he', 'IL'), // Hebrew
    // ... other locales the app supports
  ],
  // ...
)

以上代码片段的完整部分可以在课程源码中查找。

这些代理包括了实际的本地化值,并且 supportedLocales 定义了 App 支持哪些地区。上面的例子使用了一个 MaterialApp ,所以它既有 GlobalWidgetsLocalizations 用于基础 widgets,也有 MaterialWidgetsLocalizations 用于 Material wigets 的本地化。如果你使用 WidgetsApp ,则无需包括后者。注意,这两个代理虽然包括了“默认”值,但如果你想让你的 App 本地化,你仍需要提供一或多个代理作为你的 App 本地化副本。

当初始化时,WidgetsAppMaterialApp 会使用你指定的代理为你创建一个 Localizations widget。Localizations widget 可以随时从当前上下文中访问设备的地点,或者使用 Window.locale

要访问本地化文件,使用 Localizations.of() 方法来访问提供代理的特定本地化类。如需翻译,使用 intl_translation 包来取出翻译副本到 arb 文件中。把它们引入 App 中,并用 intl 来使用它们。

更多 Flutter 中国际化和本地化的细节,请访问 internationalization guide ,里面有不使用 intl 包的示例代码。

注意,在 Flutter 1.0 beta 2 之前,在 Flutter 中定义的 assets 不能在原生一侧被访问。原生定义的资源在 Flutter 中也不可用,因为它们在独立的文件夹中。

如何添加Flutter项目所需的依赖?

  • 在Android中,你可以在Gradle文件来添加依赖项;
  • 在 iOS 中,通常把依赖添加到 Podfile 中;
  • 在RN中,通常是由package.json来管理项目依赖;

Flutter 使用 Dart 构建系统和 Pub 包管理器来处理依赖。这些工具将Android 和 iOS native 包装应用程序的构建委派给相应的构建系统。

dependencies:
  flutter:
    sdk: flutter
  google_sign_in: ^3.0.3

在Flutter中,虽然在Flutter项目中的Android文件夹下有Gradle文件,但只有在添加平台相关所需的依赖关系时才使用这些文件。 否则,应该使用pubspec.yaml来声明用于Flutter的外部依赖项。

iOS也是一样,如果你的 Flutter 工程中的 iOS 文件夹中有 Podfile,请仅在添加iOS平台相关的依赖时使用它。否则,应该使用pubspec.yaml来声明用于Flutter的外部依赖项。

推荐一个用于查找Flutter插件的网站:Pub site

参考

未完待续