日益努力,而后风生水起|

Flutter开发中自动生成资源文件类

在开发程序时,我们少不了会使用到很多资源文件,一般我为了方便,会把这些资源文件都放在一个类里面,容易管理。

像下面一样:

const String iconPath = 'assets/icons';

class AppIcons {
  static String menu = '$iconPath/menu.jpg';
  ...
}

但是,如果我们在项目中用到10个或以上的资源文件的时候,一个一个定义就很麻烦,一不小心还会看走眼出错。所以,我打算自己定义一个方法,来自动生成这些文件。

我们需要知道文件夹所在位置,所以需要用到path这个包

import 'package:path/path.dart' as path;

我们需要获取要访问的资源文件路径

void generateAssets(String dir) {
  String assetsPath = path.join(path.current, dir);
}

dir是我们要访问的文件夹名称,assetsPath就是我们存储的文件夹路径。

这里之所以使用一个参数来使用,是为了方便递归资源文件夹下面的文件夹。我们现在得到的还不是一个文件夹对象,它只是String类型的路径,所以我们需要将它转成一个文件夹对象

Directory directory = Directory(assetsPaht);

在正式访问该文件夹前,我们还需要让程序知道这个文件夹是否存在,如果不存在就让它自动创建,并递归一下该方法(当然,一般我们开发时该文件夹已存在,并已经放置好了所有需要用到的资源)

if (directory.existsSync()) {
  // 文件夹存在进行的操作
  ...
} else {
  directory.createSync();
  generateAssets(dir);
}

如果存在,我们继续下一步操作。我们需要获取该文件夹下面的所有子文件或文件夹

List<FileSystemEntity> files = directory.listSync();

如果该文件夹下的子文件或文件夹为空,我们就不进行任何操作。如果存在文件或文件夹就继续操作

if (files.isNotEmpty) {
  // 文件夹不为空进行的操作
  ...
} else {
  print('该文件夹为空');
}

当然,文件夹下的内容可能不止一个,所以我们需要遍历一遍。还要判断是文件夹还是文件,来进行不同的操作

for(var file in files) {
  if (file.statSync().type == FileSystemEntityType.file) {
    // 是文件的操作
    ...
  } else {
    // 是文件夹就继续遍历
    generateAssets(file.path);
  }
}

如果是文件,我们需要存储文件名和文件夹名用来生成使用

List<String> allFile = [];
String dirName = '';
if (file.statSync().type == FileSystemEntityType.file) {
  dirName = path.basename(file.parent.path);
  String fileName = path.basename(file.path);
  allFile.add(fileName);
} 

获取了所有文件名,接下来就是最主要的,用方法来生成类。

在这个方法中,我设置了3个需要传入的参数,分别是:

  • List allFile:获取到的所有文件名称
  • String dirname:文件所在文件夹的名称,用来生成类文件名用
  • String generateDir:生成的类文件所在的文件夹
void autoGenerate(List<String> allFile, String dirName, String generateDir) {
  ...
}

先来设置生成的文件的路径

String utilsPath = path.join(path.current, 'lib', generateDir, '$dirName.dart');
File file = File(utilsPath);

如果路径文件不存在,我们就要生成。

if (file.existsSync()) {
	...
} else {
  file.createSync();
  autoGenerate(allFile, dirName, generateDir);
}

文件存在我们就写入内容

if (file.existsSync()) {
  String contents = '''
const String ${dirName}Path = 'assets/$dirName';
class App${dirName.capitalize()} {''';
  for (var file in allFile) {
    String fileName = file.contains('-')
        ? file.hump('-').split('.').first
        : file.split('.').first;
    contents += "static String $fileName = '\$${dirName}Path/$file';";
  }
  contents += '}';
  file.writeAsStringSync(contents);
} 

这里为了方便,扩展了两个String类型的方法

extension StringExtension on String {
  // 首字母大写
  String capitalize() {
    return "${this[0].toUpperCase()}${substring(1)}";
  }
	// 驼峰式命名
  String hump(String interval) {
    List<String> allChar = split(interval);
    for (var i = 1; i < allChar.length; i++) {
      allChar[i] = allChar[i].capitalize();
    }
    return allChar.join();
  }
}

还要更改一下generateAssets传入的参数,并在这个方法中调用autoGenerate

void generateAssets(String dir, String generateDir) {
  ...
    if (files.isNotEmpty) {
      ...
      autoGenerate(allFile, dirName, generateDir);
    }
  ...
}

所有的方法都写好了,现在只有调用就行。

完整代码

/// [dir]资源所在文件夹
/// [generateDir]传入生成的类所在文件夹
void generateAssets(String dir, String generateDir) {
  List<String> allFile = [];
  String dirName = '';
  String assetsPaht = path.join(path.current, dir);
  Directory directory = Directory(assetsPaht);
  if (directory.existsSync()) {
    List<FileSystemEntity> files = directory.listSync();
    if (files.isNotEmpty) {
      for (var file in files) {
        if (file.statSync().type == FileSystemEntityType.file) {
          dirName = path.basename(file.parent.path);
          String fileName = path.basename(file.path);
          allFile.add(fileName);
        } else {
          generateAssets(file.path, generateDir);
        }
      }
      autoGenerate(allFile, dirName, generateDir);
    } else {
      print('该文件夹为空');
    }
  } else {
    directory.createSync();
    generateAssets(dir, generateDir);
  }
}

void autoGenerate(List<String> allFile, String dirName, String generateDir) {
  if (allFile.isNotEmpty) {
    String utilsPath =
        path.join(path.current, 'lib', generateDir, '$dirName.dart');
    File file = File(utilsPath);
    if (file.existsSync()) {
      String contents = '''
const String ${dirName}Path = 'assets/$dirName';
class App${dirName.capitalize()} {''';
      for (var file in allFile) {
        String fileName = file.contains('-')
            ? file.hump('-').split('.').first
            : file.split('.').first;
        contents += "static String $fileName = '\$${dirName}Path/$file';";
      }
      contents += '}';
      file.writeAsStringSync(contents);
    } else {
      file.createSync();
      autoGenerate(allFile, dirName, generateDir);
    }
  }
}

extension StringExtension on String {
  String capitalize() {
    return "${this[0].toUpperCase()}${substring(1)}";
  }

  String hump(String interval) {
    List<String> allChar = split(interval);
    for (var i = 1; i < allChar.length; i++) {
      allChar[i] = allChar[i].capitalize();
    }
    return allChar.join();
  }
}

本文作者:菠萝橙子丶

本文链接:https://www.cnblogs.com/ilgnefz/p/16178948.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   菠萝橙子丶  阅读(559)  评论(1编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示
  1. 1 Shining For One Thing 赵贝尔
Shining For One Thing - 赵贝尔
00:00 / 00:00
An audio error has occurred.

Shining For One Thing (《一闪一闪亮星星》影视剧歌曲) - 赵贝尔

词:萨吉

曲:金大洲

编曲:金大洲D-Jin

制作人:金大洲D-Jin

吉他/Bass:D-Jin

合声编写/合声:赵贝尔

人声录音/编辑:张德龙@D-Jin Music Studio

混音/母带处理:George Dum

宣传推广:杨慧颖/杨佩

封面设计:HOO

OP/音乐制作出品:D-Jin Music(北京翊辰文化传媒有限公司)

(未经著作权人许可,不得翻唱、翻录或使用)

夏夜的花火

夏夜的花火

因为你在身边而深刻

因为你在身边而深刻

幸运的是我

在宇宙之间听见承诺

在宇宙之间听见承诺

嗨 是我

这一次别再错过

这一次别再错过

喜欢你该由我主动了

喜欢你该由我主动了

星星那么多

星星那么多

有数不尽的浪漫闪烁

注定这一颗

会让你刻在手臂左侧

属于我

星形心率的贴合

幸有你总在守护我

幸有你总在守护我

I fall in love

I fall in love

I see your love

遇见你才发现我在

等你到来

等你到来

Fallen star

The wonder of you

我会永远在你天空

我会永远在你天空

为你闪烁 my love

为你闪烁 my love

Shining for one thing

Shining for one thing

Shining for one thing

Shining for one thing

It's you

It's you

星星那么多

星星那么多

有数不尽的浪漫闪烁

注定这一颗

会让你刻在手臂左侧

属于我

星形心率的贴合

幸有你总在守护我

幸有你总在守护我

I fall in love

I fall in love

I see your love

遇见你才发现我在

等你到来

等你到来

Fallen star

The wonder of you

我会永远在你天空

我会永远在你天空

为你闪烁 my love

为你闪烁 my love

Shining for one thing

Shining for one thing

Shining for one thing

Shining for one thing

It's you

It's you