feat:引入TDDesign组件

This commit is contained in:
2025-07-11 14:00:58 +08:00
parent dfbbdc587f
commit b56b822e01
5 changed files with 319 additions and 383 deletions

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:food_hub_app/widgets/common/index.dart'; import 'package:food_hub_app/widgets/common/index.dart';
import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
class LoginPage extends StatefulWidget { class LoginPage extends StatefulWidget {
const LoginPage({super.key}); const LoginPage({super.key});
@@ -27,7 +28,7 @@ class _LoginPage extends State<LoginPage> {
(_formKey.currentState as FormState).save(); (_formKey.currentState as FormState).save();
Navigator.pushNamed(context, '/home'); Navigator.pushNamed(context, '/home');
} else { } else {
showErrorToast("请先输入信息"); // showErrorToast("请先输入信息");
} }
} }
@@ -184,40 +185,22 @@ class _LoginPage extends State<LoginPage> {
child: SizedBox( child: SizedBox(
height: 45, height: 45,
width: double.infinity, width: double.infinity,
child: ElevatedButton( child: TDButton(
style: ButtonStyle( text: '登录',
backgroundColor: WidgetStateProperty.all(Colors.green), size: TDButtonSize.large,
shape: WidgetStateProperty.all( type: TDButtonType.fill,
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), shape: TDButtonShape.rectangle,
), theme: TDButtonTheme.primary,
), onTap: () => loginClick(context)
child: Text( )
'登录',
style: TextStyle(fontSize: 24, color: Colors.white),
),
onPressed: () => loginClick(context),
),
), ),
); );
} }
Widget buildOtherLoginText() { Widget buildOtherLoginText() {
return SizedBox( return TDDivider(
width: double.infinity, text: '其他方式登录',
child: Stack( alignment: TextAlignment.center,
alignment: Alignment.center,
children: [
const Divider(color: Colors.grey, thickness: 0.5),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
color: Colors.white, // 与背景色一致,覆盖横线
child: const Text(
'其他方式登录',
style: TextStyle(color: Colors.grey, fontSize: 14),
),
),
],
),
); );
} }

View File

@@ -1,11 +1,11 @@
import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:food_hub_app/widgets/common/index.dart'; import 'package:food_hub_app/widgets/common/index.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart';
class RecordFormPage extends StatefulWidget { class RecordFormPage extends StatefulWidget {
const RecordFormPage({super.key}); const RecordFormPage({super.key});
@@ -17,112 +17,232 @@ class RecordFormPage extends StatefulWidget {
class _RecordFormPage extends State<RecordFormPage> { class _RecordFormPage extends State<RecordFormPage> {
final _formKey = GlobalKey<FormBuilderState>(); final _formKey = GlobalKey<FormBuilderState>();
List<TextEditingController> _controller = [];
FormController _formController = FormController();
String _selected_1 = '';
String _selected_2 = '';
String? _initLocalData;
final ImagePicker _picker = ImagePicker(); final ImagePicker _picker = ImagePicker();
XFile? _selectedImage; XFile? _selectedImage;
// 选择图片的方法 /// 整个表单存放的数据
Future<void> _pickImage(ImageSource source) async { Map<String, dynamic> _formData = {
try { "name": '',
final XFile? image = await _picker.pickImage(source: source); "date": '',
if (image != null) { "gender": '',
setState(() { "birth": '',
_selectedImage = image; "place": '',
// 更新表单字段的值 "age": "2",
_formKey.currentState?.fields['image']?.didChange(image.path); "description": "2",
}); "resume": '',
} "photo": '',
} catch (e) { };
ScaffoldMessenger.of(
context, Map<String, dynamic> _formItemNotifier = {
).showSnackBar(SnackBar(content: Text('选择图片失败: $e'))); "name": '',
} "password": '',
} "gender": '',
"birth": '',
"place": '',
"age": '2',
"description": '',
"resume": '',
"photo": "",
};
/// 定义整个校验规则
final Map<String, TDFormValidation> _validationRules = {
'name': TDFormValidation(
validate: (value) => value == null || value.isEmpty ? 'empty' : null,
errorMessage: '输入不能为空',
type: TDFormItemType.input,
),
"birth": TDFormValidation(
validate: (value) => value == null || value.isEmpty ? 'empty' : null,
errorMessage: '不能为空',
type: TDFormItemType.dateTimePicker,
),
"photo": TDFormValidation(
validate: (value) => value == null || value.isEmpty ? 'empty' : null,
errorMessage: '不能为空',
type: TDFormItemType.upLoadImg,
),
};
void confirmClick(BuildContext context) { void confirmClick(BuildContext context) {
if (_formKey.currentState?.saveAndValidate() ?? false) { if (_formKey.currentState?.saveAndValidate() ?? false) {
showSuccessToast("新增记录成功"); // showSuccessToast("新增记录成功");
} else { } else {
showErrorToast("请先提交信息"); // showErrorToast("请先提交信息");
} }
} }
// 显示图片操作弹窗(查看/删除) List<TDUploadFile> files = [];
Future<void> _showImageActionDialog(BuildContext context) async {
await showDialog( List<TDUploadFile> _onValueChanged(
context: context, List<TDUploadFile> fileList,
builder: (context) => AlertDialog( List<TDUploadFile> value,
title: const Text('图片操作'), TDUploadType event,
actions: [ ) {
// 查看图片 switch (event) {
TextButton( case TDUploadType.add:
onPressed: () { fileList.addAll(value);
Navigator.pop(context); break;
_previewImage(context); case TDUploadType.remove:
}, fileList.removeWhere((element) => element.key == value[0].key);
child: const Text('查看'), break;
), case TDUploadType.replace:
// 删除图片 final firstReplaceFile = value.first;
TextButton( final index = fileList.indexWhere(
onPressed: () { (file) => file.key == firstReplaceFile.key,
setState(() { );
_selectedImage = null; // 清空选中的图片 if (index != -1) {
fileList[index] = firstReplaceFile;
}
break;
}
return fileList;
}
@override
void initState() {
/// 三个文本型的表格单元
for (var i = 0; i < 4; i++) {
_controller.add(TextEditingController());
}
_formData.forEach((key, value) {
_formItemNotifier[key] = FormItemNotifier();
}); });
Navigator.pop(context); super.initState();
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
}
String parseDatePickerSelected(Map<String, int> selected) {
final String year = selected['year'].toString().padLeft(4, '0');
final String month = selected['month'].toString().padLeft(2, '0');
final String day = selected['day'].toString().padLeft(2, '0');
return '$year-$month-$day';
}
TDFormItem buildNameItem() {
return TDFormItem(
label: '菜谱名称',
name: 'name',
type: TDFormItemType.input,
labelWidth: 82.0,
showErrorMessage: true,
requiredMark: true,
child: TDInput(
leftContentSpace: 0,
inputDecoration: InputDecoration(
hintText: "请输入菜谱名称",
border: InputBorder.none,
hintStyle: TextStyle(color: TDTheme.of(context).grayColor6),
),
backgroundColor: Colors.white,
additionInfoColor: TDTheme.of(context).errorColor6,
showBottomDivider: false,
onChanged: (val) {
_formData['name'] = val;
}, },
child: const Text(
'删除',
style: TextStyle(color: Colors.red),
),
),
],
), ),
); );
} }
// 显示选择图片来源的弹窗(相册/相机) TDFormItem buildDateItem() {
Future<void> _showImageSourceDialog(BuildContext context) async { return TDFormItem(
await showDialog( label: '完成时间',
context: context, name: 'date',
builder: (context) => AlertDialog( labelWidth: 82.0,
title: const Text('选择图片来源'), type: TDFormItemType.dateTimePicker,
actions: [ contentAlign: TextAlign.left,
TextButton( tipAlign: TextAlign.left,
onPressed: () { hintText: '请选择完成时间',
Navigator.pop(context); select: _formData['date'],
_pickImage(ImageSource.gallery); selectFn: (BuildContext context) {
}, TDPicker.showDatePicker(
child: const Text('相册'),
),
TextButton(
onPressed: () {
Navigator.pop(context);
_pickImage(ImageSource.camera);
},
child: const Text('相机'),
),
],
),
);
}
// 预览图片(全屏查看)
void _previewImage(BuildContext context) {
Navigator.push(
context, context,
MaterialPageRoute( title: '选择时间',
builder: (context) => Scaffold( onConfirm: (selected) {
backgroundColor: Colors.black, setState(() {
body: Center( print(selected);
child: Image.file( _selected_1 =
File(_selectedImage!.path), '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}';
fit: BoxFit.contain, _formItemNotifier['birth']?.upDataForm(_selected_1);
});
Navigator.of(context).pop();
},
dateStart: [1999, 01, 01],
dateEnd: [2050, 12, 31],
initialDate: [2012, 1, 1],
);
},
);
}
TDFormItem buildImageItem() {
return TDFormItem(
label: '上传图片',
name: 'photo',
labelWidth: 82.0,
type: TDFormItemType.upLoadImg,
formItemNotifier: _formItemNotifier['photo'],
child: TDUpload(
files: files,
onError: print,
onValidate: print,
onChange: ((imgList, type) {
files = _onValueChanged(files ?? [], imgList, type);
List imgs = files.map((e) => e.remotePath ?? e.assetPath).toList();
setState(() {
_formItemNotifier['photo'].upDataForm(imgs.join(','));
});
}),
),
);
}
Widget buildFormBtnGroup() {
return Container(
decoration: BoxDecoration(color: TDTheme.of(context).whiteColor1),
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: TDButton(
text: '重置',
type: TDButtonType.fill,
theme: TDButtonTheme.light,
shape: TDButtonShape.rectangle,
onTap: () {
//用户名称
_controller[0].clear();
//密码
_controller[1].clear();
},
), ),
), ),
floatingActionButton: IconButton( SizedBox(width: 20),
icon: const Icon(Icons.close, color: Colors.white), Expanded(
onPressed: () => Navigator.pop(context), child: TDButton(
text: '提交',
type: TDButtonType.fill,
theme: TDButtonTheme.primary,
shape: TDButtonShape.rectangle,
onTap: () => {},
), ),
), ),
],
),
), ),
); );
} }
@@ -133,132 +253,20 @@ class _RecordFormPage extends State<RecordFormPage> {
appBar: AppBar(title: Text('新增记录'), backgroundColor: Colors.white), appBar: AppBar(title: Text('新增记录'), backgroundColor: Colors.white),
backgroundColor: Color(0xFFF5F5F5), backgroundColor: Color(0xFFF5F5F5),
body: Padding( body: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(10),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: TDForm(
children: <Widget>[ formController: _formController,
FormBuilder( data: _formData,
key: _formKey, rules: _validationRules,
initialValue: {'date': DateTime.now(), 'accept_terms': false}, formContentAlign: TextAlign.left,
skipDisabled: true, formShowErrorMessage: true,
child: Column( onSubmit: () => {},
crossAxisAlignment: CrossAxisAlignment.start, items: [buildNameItem(), buildDateItem(), buildImageItem()],
children: <Widget>[ btnGroup: [buildFormBtnGroup()],
formLabelText(labelText: '菜谱名称', isRequired: true),
const SizedBox(height: 5),
FormBuilderTextField(
name: 'name',
decoration: formInputDecoration(hintText: '请输入或选择菜谱名称'),
// onChanged: (val) => print(val),
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.minLength(3),
FormBuilderValidators.maxLength(70),
]),
keyboardType: TextInputType.name,
), ),
const SizedBox(height: 10),
formLabelText(labelText: '完成时间', isRequired: true),
const SizedBox(height: 5),
FormBuilderDateTimePicker(
name: 'date',
decoration: formInputDecoration(
hintText: '请选择日期',
prefixIcon: Icons.date_range,
),
inputType: InputType.date,
firstDate: DateTime(1900),
lastDate: DateTime(2100),
format: DateFormat('yyyy-MM-dd'),
// enabled: _formKey.currentState?.fields['date']?.enabled ?? true,
),
const SizedBox(height: 10),
formLabelText(labelText: '美食图片'),
const SizedBox(height: 5),
// 图片选择区域(核心优化部分)
GestureDetector(
onTap: () {
// 已选择图片时,显示操作弹窗;未选择时直接打开选择器
if (_selectedImage != null) {
_showImageActionDialog(context);
} else {
_showImageSourceDialog(context); // 弹出选择相册/相机的对话框
}
},
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: Colors.grey[300]!,
width: 1,
style: BorderStyle.solid,
),
// 有图片时显示图片,无图片时显示背景色
color:
_selectedImage == null ? Colors.grey[50] : null,
image:
_selectedImage != null
? DecorationImage(
image: FileImage(
File(_selectedImage!.path),
),
fit: BoxFit.contain,
)
: null,
),
// 初始状态显示+号;有图片时隐藏
child:
_selectedImage == null
? Center(
child: Icon(
Icons.add,
color: Colors.grey[400],
size: 48, // 大号+号,视觉更清晰
),
)
: null,
),
),
// 隐藏的表单字段(保留原功能)
FormBuilderTextField(
name: 'image',
initialValue: _selectedImage?.path ?? '',
enabled: false,
validator: (value) {
if (value == null || value.isEmpty) {
return '请选择一张图片';
}
return null;
},
),
],
),
),
const SizedBox(height: 20),
Row(
children: <Widget>[
Expanded(
child: ElevatedButton(
style: primaryButtonStyle(),
onPressed: () => confirmClick(context),
child: buttonText(text: '确认'),
),
),
const SizedBox(width: 20),
Expanded(
child: ElevatedButton(
style: cancelButtonStyle(),
onPressed: () => Navigator.pop(context),
child: buttonText(text: '取消'),
),
),
],
),
],
), ),
), ),
), ),

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; // import 'package:fluttertoast/fluttertoast.dart';
Widget formLabelText({required String labelText, bool isRequired = false}) { Widget formLabelText({required String labelText, bool isRequired = false}) {
return Text.rich( return Text.rich(
@@ -49,26 +49,26 @@ Text buttonText({required String text}) {
return Text(text, style: TextStyle(color: Colors.white)); return Text(text, style: TextStyle(color: Colors.white));
} }
void showSuccessToast(String message) { // void showSuccessToast(String message) {
Fluttertoast.showToast( // Fluttertoast.showToast(
msg: message, // msg: message,
toastLength: Toast.LENGTH_SHORT, // toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER, // gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1, // timeInSecForIosWeb: 1,
backgroundColor: Colors.green, // backgroundColor: Colors.green,
textColor: Colors.white, // textColor: Colors.white,
fontSize: 16.0, // fontSize: 16.0,
); // );
} // }
//
void showErrorToast(String message) { // void showErrorToast(String message) {
Fluttertoast.showToast( // Fluttertoast.showToast(
msg: message, // msg: message,
toastLength: Toast.LENGTH_SHORT, // toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER, // gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1, // timeInSecForIosWeb: 1,
backgroundColor: Colors.red, // backgroundColor: Colors.red,
textColor: Colors.white, // textColor: Colors.white,
fontSize: 16.0, // fontSize: 16.0,
); // );
} // }

View File

@@ -65,6 +65,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.5" version: "1.8.5"
easy_refresh:
dependency: transitive
description:
name: easy_refresh
sha256: "486e30abfcaae66c0f2c2798a10de2298eb9dc5e0bb7e1dba9328308968cae0c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.4.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@@ -155,6 +163,22 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.0.28" version: "2.0.28"
flutter_slidable:
dependency: transitive
description:
name: flutter_slidable
sha256: a857de7ea701f276fd6a6c4c67ae885b60729a3449e42766bb0e655171042801
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.2"
flutter_swiper_null_safety:
dependency: transitive
description:
name: flutter_swiper_null_safety
sha256: "5a855e0080d035c08e82f8b7fd2f106344943a30c9ab483b2584860a2f22eaaf"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.2"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@@ -165,14 +189,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
fluttertoast:
dependency: "direct main"
description:
name: fluttertoast
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "8.2.12"
form_builder_validators: form_builder_validators:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -198,13 +214,13 @@ packages:
source: hosted source: hosted
version: "4.1.2" version: "4.1.2"
image_picker: image_picker:
dependency: "direct main" dependency: "direct overridden"
description: description:
name: image_picker name: image_picker
sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" sha256: "1f498d086203360cca099d20ffea2963f48c39ce91bdd8a3b6d4a045786b02c8"
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.2" version: "1.0.8"
image_picker_android: image_picker_android:
dependency: transitive dependency: transitive
description: description:
@@ -341,6 +357,22 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.9.1" version: "1.9.1"
path_drawing:
dependency: transitive
description:
name: path_drawing
sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.1"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -402,6 +434,22 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.1.3" version: "3.1.3"
tdesign_flutter:
dependency: "direct main"
description:
name: tdesign_flutter
sha256: b36b6f939f7a585184665202b6b3acf1922728962312b65182dbbff64c3b62f2
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.3"
tdesign_flutter_adaptation:
dependency: "direct overridden"
description:
name: tdesign_flutter_adaptation
sha256: "8c5ba936abd2651472495b19dd23c525f04fb2eac6ba23de55a8b63a7c226deb"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.16.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:

View File

@@ -1,104 +1 @@
name: food_hub_app name: food_hub_app
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: ^3.7.0
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
# The following adds the Cupertino Icons fonts to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8
timelines_plus: ^1.0.7
table_calendar: ^3.1.3
custom_sliding_segmented_control: ^1.8.5
flutter_datetime_picker_plus: ^2.2.0
flutter_date_pickers: ^0.4.3
flutter_form_builder: ^10.0.0
form_builder_validators: ^11.1.2
fluttertoast: ^8.2.2
image_picker: ^1.1.2
intl: ^0.19.0
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^5.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons fonts is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/to/resolution-aware-images
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/to/asset-from-package
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the fonts family name, and a "fonts" key with a
# list giving the asset and other descriptors for the fonts. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/to/font-from-package
fonts:
- family: CustomFont
fonts:
- asset: fonts/custom.ttf