在开发程序时,我们少不了会使用到很多资源文件,一般我为了方便,会把这些资源文件都放在一个类里面,容易管理。
像下面一样:
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();