Flutter 界面开发中我们有几个痛点 :
Flutter Widgetbook 是一个用于构建和交互 Flutter 组件库的工具。它允许您在单独的应用程序中构建和演示您的 Flutter 组件,以便您可以在不运行完整应用程序的情况下进行快速迭代和测试。
使用 Flutter Widgetbook,您可以:
您可以在 Flutter 应用程序中使用 Widgetbook,也可以将其作为独立应用程序使用。在 Widgetbook 中,您可以编写 Dart 代码来定义组件和演示它们的用法。您可以使用 Flutter 提供的任何组件和库,并使用 Widgetbook 提供的一些工具来组织和显示您的组件。
前端设计规范是一组定义前端设计和开发过程中所需遵守的准则和规则的规范。它们旨在确保前端代码的一致性、可维护性、可扩展性和可重用性,并促进团队间的协作。
前端设计规范主要包括以下内容:
前端设计规范可以通过文档、工具、模板和代码库等方式来实现和维护。它们可以帮助团队提高开发效率、降低维护成本、保持代码质量和可维护性,并促进设计和开发间的协作。
https://ant.design/docs/spec/introduce-cn
https://github.com/ducafecat/flutter_develop_tips/tree/main/flutter-widgetbook
pubspec.yaml
dev_dependencies: flutter_test: sdk: flutter ... widgetbook: ^3.0.0-beta.14
注意是放在 dev_dependencies 节点下面
lib/app.widgetbook.dart
// ignore_for_file: depend_on_referenced_packages import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:widgetbook_in_flutter_course/widgets/button.dart'; void main() { runApp(const HotReload()); } class HotReload extends StatelessWidget { const HotReload({Key? key}) : super(key: key); Widget build(BuildContext context) { return Widgetbook.material( addons: [ ], directories: [ ], ); } }
运行
准备两个组件代码
lib/widgets/button.dart
import 'package:flutter/material.dart'; class MyElevatedButton extends StatelessWidget { final VoidCallback? onPressed; final String? text; final IconData? icon; final Color? textColor; final Color? buttonColor; final double? borderRadius; final double? height; final double? width; const MyElevatedButton({ Key? key, this.onPressed, this.text, this.icon, this.textColor, this.buttonColor, this.borderRadius, this.height, this.width, }) : super(key: key); Widget build(BuildContext context) { return SizedBox( height: height ?? 48.0, width: width, child: ElevatedButton( onPressed: onPressed, style: ElevatedButton.styleFrom( primary: buttonColor ?? Theme.of(context).primaryColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(borderRadius ?? 8.0), ), ), child: icon == null ? Text( text!, style: TextStyle(color: textColor ?? Colors.white), ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: textColor ?? Colors.white), SizedBox(width: 8.0), Text( text!, style: TextStyle(color: textColor ?? Colors.white), ), ], ), ), ); } }
lib/components/login.dart
import 'package:flutter/material.dart'; class LoginForm extends StatefulWidget { const LoginForm({Key? key, required this.title}) : super(key: key); final String title; State<LoginForm> createState() => _LoginFormState(); } class _LoginFormState extends State<LoginForm> { final _formKey = GlobalKey<FormState>(); final _emailController = TextEditingController(); final _passwordController = TextEditingController(); bool _isObscured = true; bool _isLoading = false; void _toggleObscure() { setState(() { _isObscured = !_isObscured; }); } void _submit() async { if (_formKey.currentState!.validate()) { setState(() { _isLoading = true; }); // Simulate a login request await Future.delayed(const Duration(seconds: 2)); setState(() { _isLoading = false; }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Logged in successfully!'), ), ); } } Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(widget.title)), body: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ TextFormField( controller: _emailController, keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: 'Email', ), validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your email'; } if (!value.contains('@')) { return 'Please enter a valid email address'; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: _passwordController, obscureText: _isObscured, decoration: InputDecoration( labelText: 'Password', suffixIcon: IconButton( icon: Icon( _isObscured ? Icons.visibility : Icons.visibility_off, ), onPressed: _toggleObscure, ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your password'; } if (value.length < 6) { return 'Password must be at least 6 characters long'; } return null; }, ), const SizedBox(height: 32), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _isLoading ? null : _submit, child: _isLoading ? const CircularProgressIndicator() : const Text('Log in'), ), ), ], ), ), ); } }
分类1 - 公共组件
WidgetbookCategory buildWidgetbookCategory() { return WidgetbookCategory( name: '公共组件', children: [ WidgetbookComponent( name: '按钮', useCases: [ WidgetbookUseCase.center( name: "红色背景", child: MyElevatedButton( onPressed: () => print("Button pressed"), text: "Click me", icon: Icons.arrow_forward, buttonColor: Colors.red, borderRadius: 16.0, height: 60.0, width: double.infinity, ), ), WidgetbookUseCase.center( name: "蓝色色背景", child: MyElevatedButton( onPressed: () => print("Button pressed"), text: "Click me", icon: Icons.arrow_forward, buttonColor: Colors.blue, borderRadius: 16.0, height: 60.0, width: double.infinity, ), ) ], ), ], ); }
分类2 - 业务组件
WidgetbookCategory buildWidgetbookCategory2() { return WidgetbookCategory( name: '业务组件', children: [ WidgetbookComponent( name: '系统常用', useCases: [ WidgetbookUseCase( name: "登录界面", builder: (BuildContext context) { return LoginForm( title: context.knobs.text( label: '标题 [title]', initialValue: '用户登录', ), ); }, ), WidgetbookUseCase( name: "注册界面", builder: (BuildContext context) { return LoginForm( title: context.knobs.text( label: '标题 [title]', initialValue: '用户注册', ), ); }, ), ], ), ], ); }
通过 knobs 的方式设置调试参数
其它参数类型
build 函数
Widget build(BuildContext context) { return Widgetbook.material( addons: [ ], directories: [ // 基础组件 buildWidgetbookCategory(), // 业务组件 buildWidgetbookCategory2(), ], ); }
输出
主题
MaterialThemeAddon buildMaterialThemeAddon() { return MaterialThemeAddon( setting: MaterialThemeSetting.firstAsSelected(themes: [ WidgetbookTheme(name: "dark", data: ThemeData.dark()), WidgetbookTheme(name: "light", data: ThemeData.light()), ])); }
字体尺寸
TextScaleAddon buildTextScaleAddon() { return TextScaleAddon( setting: TextScaleSetting.firstAsSelected( textScales: [1.0, 1.25, 1.5, 1.75, 2])); }
build 函数
Widget build(BuildContext context) { return Widgetbook.material( addons: [ // 主题 buildMaterialThemeAddon(), // 字体大小 buildTextScaleAddon(), ], directories: [ // 基础组件 buildWidgetbookCategory(), // 业务组件 buildWidgetbookCategory2(), ], ); }
输出
其它 addon
Flutter Widgetbook 对前端开发工作有以下好处:
总之,Flutter Widgetbook 是一个有用的工具,可以帮助前端开发人员更轻松地构建和测试 Flutter 组件,从而提高开发效率、保持代码质量和可维护性,并促进跨团队协作和知识共享,最终提高用户体验和用户满意度。
ducafecat.com
end
Copyright 2023 ducafecat. All rights reserved.
微信: ducafecat, line: ducafecat,京ICP备2021009050号-3