Flutter通用组件插件tch_common_widgets的使用
Flutter通用组件插件tch_common_widgets的使用
tch_common_widgets
是一个用于Flutter项目的通用组件包。它包含了许多在多个项目中被复用的自定义组件,同时也支持全局主题定制。该包由 Tomas Chyly 开发,并且在一些功能上依赖于另一个包 tch_appliable_core
。
平台注意事项
虽然我在多个平台上使用过Flutter,但我的主要关注点是在移动设备和桌面应用上。因此,某些组件和特性可能不适用于Web平台,但应该可以在其他平台上正常工作。我个人认为Flutter目前还不完全适合Web开发。
开发注意事项
由于时间限制,文档可能有些过时,但是该包本身会继续得到维护和发展。
目录
- 安装
- 主题
- 组件
- 对话框
- 路线图
安装
在你的项目的 pubspec.yaml
文件中添加以下依赖:
dependencies:
tch_common_widgets: ^0.37.1+1
如果IDE没有自动导入,可以手动添加:
import 'package:tch_common_widgets/tch_common_widgets.dart';
主题
CommonTheme 的设置与使用
首先,在 lib/core/AppTheme.dart
文件中创建颜色常量、文本样式和尺寸常量,然后使用它们来创建兼容 CommonTheme
的样式。以下是示例代码:
const kColorPrimary = const Color(0xFF1a1a1a);
const kColorPrimaryLight = const Color(0xFF404040);
const kColorPrimaryDark = const Color(0xFF000000);
const kColorSecondary = kColorGold;
const kColorSecondaryLight = kColorGoldLight;
const kColorSecondaryDark = kColorGoldDarker;
const kColorTextPrimary = kColorSilver;
const kFontFamily = 'Custom Font Family Name';
const kText = const TextStyle(color: kColorTextPrimary, fontSize: 16);
const kTextHeadline = const TextStyle(color: kColorTextPrimary, fontSize: 20);
/// 构建方法,提供给CoreApp或MaterialApp,它将所有页面包裹在CommonTheme中
/// 自定义CommonTheme以适应应用需求
Widget appThemeBuilder(BuildContext context, Widget child) {
/// 根据操作系统更改圆角半径
BorderRadius platformBorderRadius = const BorderRadius.all(const Radius.circular(8));
if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) {
platformBorderRadius = BorderRadius.circular(0);
}
/// 默认为IconButtonWidgets设置样式,使其更适合桌面使用
final kIconButtonStyle = IconButtonStyle(
width: kMinInteractiveSizeNotTouch + kCommonHorizontalMarginHalf,
height: kMinInteractiveSizeNotTouch + kCommonVerticalMarginHalf,
iconWidth: kIconSizeNotTouch,
iconHeight: kIconSizeNotTouch,
color: kColorTextPrimary,
borderRadius: platformBorderRadius,
);
/// AppBar中的IconButtonWidgets具有不同的默认样式
const kAppBarIconButtonStyle = const IconButtonStyle(
variant: IconButtonVariant.IconOnly,
color: kColorTextPrimary,
borderRadius: platformBorderRadius,
);
final OutlineInputBorder platformInputBorder = OutlineInputBorder(
borderSide: const BorderSide(
width: 1,
),
borderRadius: platformBorderRadius,
);
/// 所有TextFormFieldWidgets的默认样式
final kTextFormFieldStyle = TextFormFieldStyle(
inputDecoration: TextFormFieldStyle().inputDecoration.copyWith(
enabledBorder: platformInputBorder,
disabledBorder: platformInputBorder,
focusedBorder: platformInputBorder,
errorBorder: platformInputBorder,
focusedErrorBorder: platformInputBorder,
),
borderColor: kColorGold,
fillColorDisabled: kColorSilver,
disabledBorderColor: kColorSilverDarker,
errorColor: kColorRed,
);
/// 修改默认样式以获取电子邮件字段的样式
final TextFormFieldStyle kEmailTextFormFieldStyle = kTextFormFieldStyle.copyWith(
textCapitalization: TextCapitalization.none,
keyboardType: TextInputType.emailAddress,
validations: [
FormFieldValidation(
validator: validateEmail,
errorText: '请输入有效的电子邮件地址', // 或者使用tt('form.email.error'),如果你使用的是CoreApp Translator
),
],
);
return AppTheme(
child: child,
fontFamily: prefsInt(PREFS_FANCY_FONT) == 1 ? kFontFamily : null,
buttonsStyle: ButtonsStyle(
iconButtonStyle: kIconButtonStyle,
),
appBarIconButtonStyle: kAppBarIconButtonStyle,
formStyle: FormStyle(
textFormFieldStyle: kTextFormFieldStyle,
),
emailTextFormFieldStyle: kEmailTextFormFieldStyle,
);
}
/// 自定义AppTheme扩展CommonTheme以允许自定义样式
class AppTheme extends CommonTheme {
final IconButtonStyle appBarIconButtonStyle;
final TextFormFieldStyle emailTextFormFieldStyle;
/// AppTheme初始化
AppTheme({
required Widget child,
String? fontFamily,
required ButtonsStyle buttonsStyle,
required this.appBarIconButtonStyle,
required DialogsStyle dialogsStyle,
required FormStyle formStyle,
required this.emailTextFormFieldStyle,
}) : super(
/// 子节点需要是CommonTheme,否则通用组件将无法正常工作
child: CommonTheme(
child: child,
fontFamily: fontFamily,
buttonsStyle: buttonsStyle,
dialogsStyle: dialogsStyle,
formStyle: formStyle,
),
fontFamily: fontFamily,
buttonsStyle: buttonsStyle,
dialogsStyle: dialogsStyle,
formStyle: formStyle,
);
}
要使用你定义的非默认样式,只需将它们传递给相应的组件即可。例如:
...
final appTheme = CommonTheme.of<AppTheme>(context)!;
...
/// 使用kAppBarIconButtonStyle样式为AppBar中的IconButtonWidgets
IconButtonWidget(
style: appTheme.appBarIconButtonStyle,
svgAssetPath: 'images/back.svg',
onTap: () {
Navigator.pop(context);
},
);
...
...
final appTheme = CommonTheme.of<AppTheme>(context)!;
...
/// kEmailTextFormFieldStyle 确保此字段看起来和行为都像电子邮件字段
TextFormFieldWidget(
style: appTheme.emailTextFormFieldStyle,
controller: _emailController,
focusNode: _emailFocus,
nextFocus: _subjectFocus,
label: 'Email',
textInputAction: TextInputAction.next,
),
...
如果想在任何地方访问 CommonTheme
并在某些组件中临时修改样式:
final commonTheme = CommonTheme.of(context)!;
...
/// 多行文本字段,临时修改默认样式以实现句子首字母大写
TextFormFieldWidget(
style: commonTheme.formStyle.textFormFieldStyle.copyWith(
textCapitalization: TextCapitalization.sentences,
),
controller: _messageController,
focusNode: _messageFocus,
label: tt('feedback.screen.message'),
lines: 3,
validations: [
FormFieldValidation(
validator: validateRequired,
errorText: tt('feedback.screen.message.error'),
),
],
),
...
在整个应用中应用你的CommonTheme
...
@override
Widget build(BuildContext context) {
return CoreApp( // 如果你不使用我的Core包,则使用MaterialApp
...
builder: appThemeBuilder,
theme: ThemeData( /// 你可以将CommonTheme与Material主题结合起来
backgroundColor: kColorPrimaryLight,
primaryColor: kColorPrimary,
primaryColorLight: kColorPrimaryLight,
primaryColorDark: kColorPrimaryDark,
accentColor: kColorSecondary,
splashColor: kColorSecondary,
shadowColor: kColorShadow,
),
...
);
}
...
组件
CommonSpaces
- 与
CommonTheme
兼容,也可以单独使用。
这些是一组用于轻松和标准地在其他组件之间插入间距的组件。
PreferencesSwitchWidget
- 与
CommonTheme
兼容,也可以单独使用。 - 需要
tch_appliable_core
包来处理偏好设置。
简单的设置切换/开关,从偏好设置中获取并切换整数,将其作为布尔值使用。
SwitchToggleWidget
- 与
CommonTheme
兼容,也可以单独使用。
Switch的替代组件,包装了 IconButtonWidget
和样式。
TextFormFieldWidget
- 与
CommonTheme
兼容,也可以单独使用。 - 自定义解决方案,修复了Flutter iOS版本的自动更正问题!
- 该解决方案自Flutter >= 3.16.0后不再必要。
封装了 TextFormField
以进行额外的样式调整和功能,主要与 CommonTheme
一起使用。有两种变体:Material和Cupertino风格。
如果你在 CommonTheme
中设置或直接传递给组件:
TextFormFieldStyle(
...
iOSUseNativeTextField: true,
...
)
更多关于Flutter通用组件插件tch_common_widgets的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter通用组件插件tch_common_widgets的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用tch_common_widgets
插件的一个简单示例。tch_common_widgets
是一个假设的通用组件插件,因此具体API可能会有所不同,但我会根据常见的Flutter插件使用模式给出一个示例。
首先,你需要确保你的Flutter项目中已经添加了tch_common_widgets
插件。你可以通过修改pubspec.yaml
文件来添加依赖:
dependencies:
flutter:
sdk: flutter
tch_common_widgets: ^x.y.z # 替换为实际的版本号
然后运行flutter pub get
来安装依赖。
假设tch_common_widgets
插件提供了一些常用的组件,比如一个自定义的按钮(CustomButton
)和一个自定义的加载指示器(CustomLoadingIndicator
)。以下是如何在你的Flutter应用中使用这些组件的代码示例:
import 'package:flutter/material.dart';
import 'package:tch_common_widgets/tch_common_widgets.dart'; // 导入插件
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool isLoading = false;
void handleButtonClick() {
setState(() {
isLoading = true;
// 模拟加载过程
Future.delayed(Duration(seconds: 2), () {
setState(() {
isLoading = false;
});
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('tch_common_widgets Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 使用自定义按钮组件
CustomButton(
text: 'Click Me',
onPressed: handleButtonClick,
),
SizedBox(height: 20),
// 根据加载状态显示不同的组件
if (isLoading)
CustomLoadingIndicator() // 显示加载指示器
else
Text('Loading complete!'), // 加载完成后显示文本
],
),
),
);
}
}
在这个示例中:
CustomButton
是一个假设的自定义按钮组件,它接受一个文本标签和一个点击事件回调。CustomLoadingIndicator
是一个假设的自定义加载指示器组件。- 在
_MyHomePageState
中,我们有一个布尔变量isLoading
来控制加载状态。点击按钮时,我们设置isLoading
为true
,模拟一个加载过程,2秒后将其设置回false
。 - 根据
isLoading
的值,我们在UI中显示不同的组件:加载中时显示CustomLoadingIndicator
,加载完成后显示文本。
请注意,由于tch_common_widgets
是一个假设的插件,上述代码中的CustomButton
和CustomLoadingIndicator
组件及其API可能并不真实存在。你需要根据实际的tch_common_widgets
插件文档来调整代码。通常,插件的README文件或官方文档会提供详细的组件使用说明和示例代码。