Flutter使用flutter_gen管理资源文件

pub地址:

https://pub.dev/packages/flutter_gen

1.添加依赖

在你的pubspec.yaml文件中添加flutter_gen作为开发依赖

dependencies:
  build_runner:
  flutter_gen_runner:

2.配置pubspec.yaml

在pubspec.yaml文件中,配置flutter_gen的参数。指定输出路径和资源路径。

flutter_gen:
  output: lib/gen/ # Optional (default: lib/gen/)
  lineLength: 80   # Optional (default: 80)
  # Optional
  integrations:
    flutter_svg: true   # .svg  Assets.images.icons.paint.svg()
    flare_flutter: true # .flr  Assets.flare.penguin.flare()
    rive: true          # .flr  Assets.rive.vehicles.rive()
    lottie: true        # .json Assets.lottie.hamburgerArrow.lottie()
  colors:
    inputs:
      - assets/colors/colors.xml

flutter:
  uses-material-design: true
  assets:
    - assets/images/tab_home_default.png
    - assets/images/tab_home_selected.png
    - assets/images/tab_category_default.png
    - assets/images/tab_category_selected.png
    - assets/images/tab_mine_default.png
    - assets/images/tab_mine_selected.png
    - assets/images/photo.png
    - assets/images/font.png
    - assets/files/mov_file.mov
    - assets/files/mp3_file.mp3
    - assets/files/mp4_file.mp4
    - assets/files/pdf_file.pdf
    - assets/files/svga_file.svga
    - assets/files/txt_file.txt
    - assets/files/xlsx_file.xlsx
    - assets/files/zip_file.zip

  fonts:
    - family: simkai
      fonts:
        - asset: assets/fonts/simkai.ttf
    - family: SourceHanSerifCNBold
      fonts:
        - asset: assets/fonts/SourceHanSerifCN-Bold.otf
          weight: 700

3.运行生成命令

使用Flutter命令行工具运行pub get来安装新的依赖

$ flutter pub get

使用命令行工具运行命令生成资源文件

$ dart run build_runner build
或
$ flutter packages pub run build_runner build
或
$ flutter packages pub run build_runner build --delete-conflicting-outputs

如果图片资源发生变化,只需更新pubspec.yaml文件并重新运行生成资源文件的命令即可更新资源引用。

4.使用图片和其它资源文件

flutter_gen会在指定的输出目录(例如lib/gen/)中生成一个assets.gen.dart文件,里面包含了所有的资源引用。

使用图片
import 'gen/assets.gen.dart';

Image.asset(
  Assets.images.photo.path, //'assets/images/photo.png',
  width: 50,
  height: 50,
),

Assets.images.font.image(
  width: 100,
  height: 100,
)
使用其它文件
import 'package:flutter/services.dart' show rootBundle;
import 'dart:typed_data';

  var arr = [
    Assets.files.txtFile,
    Assets.files.movFile,
    Assets.files.mp3File,
    Assets.files.mp4File,
    Assets.files.pdfFile,
    Assets.files.svgaFile,
    Assets.files.xlsxFile,
    Assets.files.zipFile
  ];

// 获取文件中的字符串
Future<String> loadAsset(String path) async {
  try {
    var str = await rootBundle.loadString(path);
    return str;
  } catch (e) {
    return "获取失败";
  }
}

// 获取文件二进制数据
Future<ByteData> loadAssetData(String path) async {
  try {
    var data = await rootBundle.load(path);
    return data;
  } catch (e) {
    return ByteData(0);
  }
}

Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      FutureBuilder<String>(
        future: loadAsset(Assets.files.txtFile),
        builder: (BuildContext context,
            AsyncSnapshot<String> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            return Text(snapshot.data ?? '');
          } else {
            return const CircularProgressIndicator();
          }
        },
      ),

      FutureBuilder<ByteData>(
        future: loadAssetData(Assets.files.mp3File),
        builder: (BuildContext context,
            AsyncSnapshot<ByteData> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            // 这里你可以使用 snapshot.data 来访问文件的二进制数据
            Uint8List data =
                snapshot.data?.buffer.asUint8List() ??
                    Uint8List(0);
            return Container(
              child: Text(data.toString()),
            );
          } else {
            return const CircularProgressIndicator();
          }
        },
      ),
    ],
  ),
资源文件适配

Flutter默认会按照这样的文件夹结构来寻找合适的资源:

  • .../image.png — 默认图片,适用于1.0x设备像素比的屏幕。

  • .../2.0x/image.png — 适用于2.0x设备像素比的屏幕。

  • .../3.0x/image.png — 适用于3.0x设备像素比的屏幕。

当你在应用中引用图像时,只需引用默认的图片路径(.../image.png),Flutter会自动根据设备的像素密度来加载正确的资源文件。如果你的应用不需要支持多种像素密度的图像,那么你也可以只提供默认的图像资源而不创建这些文件夹。

如果你决定支持不同的像素密度,确保为每个分辨率提供相应的图像资源,并按照上述结构放置它们。这样,Flutter就可以为不同的设备屏幕自动选择最合适的资源。

flutter_gen生成的assets.gen.dart
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
///  FlutterGen
/// *****************************************************

// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use

import 'package:flutter/widgets.dart';

class $AssetsFilesGen {
  const $AssetsFilesGen();

  /// File path: assets/files/mov_file.mov
  String get movFile => 'assets/files/mov_file.mov';

  /// File path: assets/files/mp3_file.mp3
  String get mp3File => 'assets/files/mp3_file.mp3';

  /// File path: assets/files/mp4_file.mp4
  String get mp4File => 'assets/files/mp4_file.mp4';

  /// File path: assets/files/pdf_file.pdf
  String get pdfFile => 'assets/files/pdf_file.pdf';

  /// File path: assets/files/svga_file.svga
  String get svgaFile => 'assets/files/svga_file.svga';

  /// File path: assets/files/txt_file.txt
  String get txtFile => 'assets/files/txt_file.txt';

  /// File path: assets/files/xlsx_file.xlsx
  String get xlsxFile => 'assets/files/xlsx_file.xlsx';

  /// File path: assets/files/zip_file.zip
  String get zipFile => 'assets/files/zip_file.zip';

  /// List of all assets
  List<String> get values => [
        movFile,
        mp3File,
        mp4File,
        pdfFile,
        svgaFile,
        txtFile,
        xlsxFile,
        zipFile
      ];
}

class $AssetsImagesGen {
  const $AssetsImagesGen();

  /// File path: assets/images/font.png
  AssetGenImage get font => const AssetGenImage('assets/images/font.png');

  /// File path: assets/images/photo.png
  AssetGenImage get photo => const AssetGenImage('assets/images/photo.png');

  /// File path: assets/images/tab_category_default.png
  AssetGenImage get tabCategoryDefault =>
      const AssetGenImage('assets/images/tab_category_default.png');

  /// File path: assets/images/tab_category_selected.png
  AssetGenImage get tabCategorySelected =>
      const AssetGenImage('assets/images/tab_category_selected.png');

  /// File path: assets/images/tab_home_default.png
  AssetGenImage get tabHomeDefault =>
      const AssetGenImage('assets/images/tab_home_default.png');

  /// File path: assets/images/tab_home_selected.png
  AssetGenImage get tabHomeSelected =>
      const AssetGenImage('assets/images/tab_home_selected.png');

  /// File path: assets/images/tab_mine_default.png
  AssetGenImage get tabMineDefault =>
      const AssetGenImage('assets/images/tab_mine_default.png');

  /// File path: assets/images/tab_mine_selected.png
  AssetGenImage get tabMineSelected =>
      const AssetGenImage('assets/images/tab_mine_selected.png');

  /// List of all assets
  List<AssetGenImage> get values => [
        font,
        photo,
        tabCategoryDefault,
        tabCategorySelected,
        tabHomeDefault,
        tabHomeSelected,
        tabMineDefault,
        tabMineSelected
      ];
}

class Assets {
  Assets._();

  static const $AssetsFilesGen files = $AssetsFilesGen();
  static const $AssetsImagesGen images = $AssetsImagesGen();
}

class AssetGenImage {
  const AssetGenImage(this._assetName);

  final String _assetName;

  Image image({
    Key? key,
    AssetBundle? bundle,
    ImageFrameBuilder? frameBuilder,
    ImageErrorWidgetBuilder? errorBuilder,
    String? semanticLabel,
    bool excludeFromSemantics = false,
    double? scale,
    double? width,
    double? height,
    Color? color,
    Animation<double>? opacity,
    BlendMode? colorBlendMode,
    BoxFit? fit,
    AlignmentGeometry alignment = Alignment.center,
    ImageRepeat repeat = ImageRepeat.noRepeat,
    Rect? centerSlice,
    bool matchTextDirection = false,
    bool gaplessPlayback = false,
    bool isAntiAlias = false,
    String? package,
    FilterQuality filterQuality = FilterQuality.low,
    int? cacheWidth,
    int? cacheHeight,
  }) {
    return Image.asset(
      _assetName,
      key: key,
      bundle: bundle,
      frameBuilder: frameBuilder,
      errorBuilder: errorBuilder,
      semanticLabel: semanticLabel,
      excludeFromSemantics: excludeFromSemantics,
      scale: scale,
      width: width,
      height: height,
      color: color,
      opacity: opacity,
      colorBlendMode: colorBlendMode,
      fit: fit,
      alignment: alignment,
      repeat: repeat,
      centerSlice: centerSlice,
      matchTextDirection: matchTextDirection,
      gaplessPlayback: gaplessPlayback,
      isAntiAlias: isAntiAlias,
      package: package,
      filterQuality: filterQuality,
      cacheWidth: cacheWidth,
      cacheHeight: cacheHeight,
    );
  }

  ImageProvider provider({
    AssetBundle? bundle,
    String? package,
  }) {
    return AssetImage(
      _assetName,
      bundle: bundle,
      package: package,
    );
  }

  String get path => _assetName;

  String get keyName => _assetName;
}

5.使用颜色资源文件

flutter_gen会在指定的输出目录(例如lib/gen/)中生成一个colors.gen.dart文件,里面包含了颜色的资源引用。

使用颜色
import 'gen/colors.gen.dart';

child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      const Text(
        "字符串1",
        style: TextStyle(
          color: Colors.red,
        ),
      ),
      const Text(
        "字符串1",
        style: TextStyle(
          color: ColorName.textColor,
        ),
      ),
      Text(
        "字符串3",
        style: TextStyle(
          color: ColorName.themeColor[300],
        ),
      ),
      Text(
        "字符串4",
        style: TextStyle(
          color: ColorName.themeColorAccent[400],
        ),
      ),
    ],
  ),
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="text_color" type="material">#333333</color>
    <color name="theme_color" type="material material-accent">#333333</color>
</resources>
flutter_gen生成的colors.gen.dart
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
///  FlutterGen
/// *****************************************************

// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use

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

class ColorName {
  ColorName._();

  /// Color: #FF000000
  static const Color black = Color(0xFF000000);

  /// MaterialColor:
  ///   50: #FFE7E7E7
  ///   100: #FFC2C2C2
  ///   200: #FF999999
  ///   300: #FF707070
  ///   400: #FF525252
  ///   500: #FF333333
  ///   600: #FF2E2E2E
  ///   700: #FF272727
  ///   800: #FF202020
  ///   900: #FF141414
  static const MaterialColor textColor = MaterialColor(
    0xFF333333,
    <int, Color>{
      50: Color(0xFFE7E7E7),
      100: Color(0xFFC2C2C2),
      200: Color(0xFF999999),
      300: Color(0xFF707070),
      400: Color(0xFF525252),
      500: Color(0xFF333333),
      600: Color(0xFF2E2E2E),
      700: Color(0xFF272727),
      800: Color(0xFF202020),
      900: Color(0xFF141414),
    },
  );

  /// MaterialColor:
  ///   50: #FFE7E7E7
  ///   100: #FFC2C2C2
  ///   200: #FF999999
  ///   300: #FF707070
  ///   400: #FF525252
  ///   500: #FF333333
  ///   600: #FF2E2E2E
  ///   700: #FF272727
  ///   800: #FF202020
  ///   900: #FF141414
  static const MaterialColor themeColor = MaterialColor(
    0xFF333333,
    <int, Color>{
      50: Color(0xFFE7E7E7),
      100: Color(0xFFC2C2C2),
      200: Color(0xFF999999),
      300: Color(0xFF707070),
      400: Color(0xFF525252),
      500: Color(0xFF333333),
      600: Color(0xFF2E2E2E),
      700: Color(0xFF272727),
      800: Color(0xFF202020),
      900: Color(0xFF141414),
    },
  );

  /// MaterialAccentColor:
  ///   100: #FFE82D2D
  ///   200: #FFC21616
  ///   400: #FFBE0000
  ///   700: #FFAF0000
  static const MaterialAccentColor themeColorAccent = MaterialAccentColor(
    0xFFC21616,
    <int, Color>{
      100: Color(0xFFE82D2D),
      200: Color(0xFFC21616),
      400: Color(0xFFBE0000),
      700: Color(0xFFAF0000),
    },
  );

  /// Color: #FFFFFFFF
  static const Color white = Color(0xFFFFFFFF);
}

6.使用字体资源文件

flutter_gen会在指定的输出目录(例如lib/gen/)中生成一个colors.gen.dart文件,里面包含了颜色的资源引用。

使用字体
import 'gen/fonts.gen.dart';

const Text(
  "字体",
  style: TextStyle(
    fontFamily: FontFamily.simkai,
    fontFamilyFallback: [FontFamily.sourceHanSerifCNBold],
  ),
),

通常,fontFamilyFallback用于指定一系列的备选字体,以确保在主字体不支持某些字符时,文本仍然可以用其他字体显示。如果你确定FontFamily.simkai能够支持你需要显示的所有字符,那么就不需要在fontFamilyFallback中再次指定它。相反,如果你有理由相信FontFamily.simkai可能不包含某些字符,那么应该在fontFamilyFallback中指定一个或多个不同的备选字体。

flutter_gen生成的fonts.gen.dart
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
///  FlutterGen
/// *****************************************************

// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use

class FontFamily {
  FontFamily._();

  /// Font family: SourceHanSerifCNBold
  static const String sourceHanSerifCNBold = 'SourceHanSerifCNBold';

  /// Font family: simkai
  static const String simkai = 'simkai';
}

猜你喜欢

转载自blog.csdn.net/u012881779/article/details/134722586
今日推荐