Flutter设计系统插件easy_design_system的使用
Flutter设计系统插件easy_design_system的使用
Easy Design System
Easy Design System 是一个为 Flutter 设计的优雅且易于使用的 UI/UX 设计库,旨在增强您的应用程序的美学和用户体验,而无需学习任何新知识。这是一个开源项目,您可以对其进行 Fork 并提交 PR。
再次强调,无需学习任何新知识。只需安装该包并在 MaterialApp
中应用主题即可。
开始使用
要了解更多,请访问 Easy Design System 文档网站。
入口屏幕
Easy Design System 提供了用于您的应用程序的启动屏幕。
基本轮播入口 | 波浪形轮播入口 | 圆形轮播入口 |
---|---|---|
![]() |
![]() |
![]() |
示例
以下是 Easy Design System (SDS) 的一些示例。
漫画主题 | 简洁主题 |
---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
使用方法
Easy Design System 遵循 Flutter 编程风格。您可以继续使用 Flutter 进行编码,而无需了解如何应用 UI 设计。
例如,SDS 提供了 ComicTheme
,您可以像下面这样使用它:
Theme(
data: ComicTheme.of(context),
child: const ListTile(
title: Text('Item 1'),
subtitle: Text('Subtitle 1'),
leading: Icon(Icons.access_time),
trailing: Icon(Icons.arrow_forward_ios),
),
),
正如您所知,这是 Flutter 的常规用法。
您也可以更简洁地使用 ComicTheme
,如下所示:
const ComicTheme(
child: ListTile(
title: Text('Item 2'),
subtitle: Text('Subtitle 2'),
leading: Icon(Icons.access_alarm),
trailing: Icon(Icons.arrow_forward_ios),
),
),
更多细节,请访问 Easy Design System 文档网站。
学习内容
漫画主题
漫画主题使用以下样式:
- 外边框带颜色。
- 背景颜色带有表面颜色。
在使用 ComicTheme
小部件之前,可以设置 comicBorderWidth
来控制外边框的宽度:
Widget build(BuildContext context) {
comicBorderWidth = 1.0;
return MaterialApp.router(
theme: ComicTheme.of(context).copyWith(),
);
}
简洁主题
简洁主题使用以下样式:
- 背景颜色带有主要容器颜色。
贡献
- Fork 并提交 PR。
- 在 Git 仓库上留下您的问题。
如何构建和运行
- Fork(或克隆)该项目。
- 运行示例项目。
完整示例代码
下面是完整的示例代码,展示了如何使用 easy_design_system
插件。
import 'package:example/app.state.dart';
import 'package:example/contents/comic_border.content.dart';
import 'package:example/contents/comic_icon_button_theme_data.content.dart';
import 'package:example/contents/comic_text_button_theme_data.content.dart';
import 'package:example/contents/home.content.dart';
import 'package:example/contents/sleek_icon_button_theme_data.content.dart';
import 'package:example/screens/color_scheme/color_scheme.screen.dart';
import 'package:easy_design_system/easy_design_system.dart';
import 'package:example/screens/demo/sleek/sleek.theme.screen.dart';
import 'package:example/screens/demo/login/sleek_login.demo.dart';
import 'package:example/screens/dialog/dialog.screen.dart';
import 'package:example/screens/app_bar/app_bar.screen.dart';
import 'package:example/screens/badge/badge.screen.dart';
import 'package:example/screens/bottom_app_bar/bottom_app_bar.screen.dart';
import 'package:example/screens/bottom_sheet/bottom_sheet.screen.dart';
import 'package:example/screens/buttons/buttons.screen.dart';
import 'package:example/screens/card/card.screen.dart';
import 'package:example/screens/checkbox/checkbox.screen.dart';
import 'package:example/screens/chip/chip.screen.dart';
import 'package:example/screens/demo/comic/comic.theme.screen.dart';
import 'package:example/screens/divider/divider.screen.dart';
import 'package:example/screens/dropdown/dropdown.screen.dart';
import 'package:example/screens/floating_action_button/floating_action_button.screen.dart';
import 'package:example/screens/icon_buttons/icon_buttons.screen.dart';
import 'package:example/screens/list_tile/list_tile.screen.dart';
import 'package:example/screens/entry/basic_carousel_entry.screen.dart';
import 'package:example/screens/entry/round_carousel_entry.screen.dart';
import 'package:example/screens/entry/wave_carousel_entry.screen.dart';
import 'package:example/screens/demo/login/comic_login.demo.dart';
import 'package:example/screens/list_view/comic.list_view.screen.dart';
import 'package:example/screens/list_view/sleek.list_view.screen.dart';
import 'package:example/screens/navigation_drawer/navigation_drawer.screen.dart';
import 'package:example/screens/navigation_bar/navigation_bar.screen.dart';
import 'package:example/screens/navigation_rail.dart/navigation_rail.screen.dart';
import 'package:example/screens/birthdate_picker/birthdate.picker.screen.dart';
import 'package:example/screens/progress_indicator/progress_indicator.screen.dart';
import 'package:example/screens/radio_button/radio_button.dart';
import 'package:example/screens/search/search.screen.dart';
import 'package:example/screens/segmented_button/segmented_button.dart';
import 'package:example/screens/setting/setting.screen.dart';
import 'package:example/screens/sleep_walker/sleep_walker.screen.dart';
import 'package:example/screens/snackbar/snackbars.screen.dart';
import 'package:example/screens/switch/switch.dart';
import 'package:example/screens/tab_bar/tab_bar.screen.dart';
import 'package:example/screens/text_field/text_field.screen.dart';
import 'package:example/screens/text_form_field/text_form_field.screen.dart';
import 'package:example/screens/toggle_button/toggle_button.dart';
import 'package:example/screens/ui_widgets/comic_theme.screen.dart';
import 'package:example/screens/ui_widgets/sleek_theme.screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:easystate/easystate.dart';
void main() {
runApp(
EasyState(
state: AppState(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
themeMode: ThemeMode.dark,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const MyHomePage(title: 'Social Design System'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int selectedIndex = 0;
bool wideScreen = false;
bool showSideMenu = false;
[@override](/user/override)
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
if (const String.fromEnvironment('MODE') == 'noe') {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const BirthdatePickerScreen()));
}
});
}
[@override](/user/override)
void didChangeDependencies() {
super.didChangeDependencies();
final double width = MediaQuery.of(context).size.width;
wideScreen = width > 600;
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
sideMenu(),
Expanded(
child: EasyStateBuilder<AppState>(
builder: (_, state) => state.content,
),
),
],
),
bottomNavigationBar: wideScreen
? null
: SafeArea(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
EasyState.of<AppState>(context).setContent(
const HomeContent(),
);
showSideMenu = false;
setState(() {});
},
child: const Text('Home')),
ElevatedButton(
onPressed: () {
showSideMenu = !showSideMenu;
setState(() {});
},
child: const Text('Menu')),
],
),
),
);
}
Widget sideMenu() {
if (!wideScreen && !showSideMenu) {
return const SizedBox.shrink();
}
return SingleChildScrollView(
child: Container(
padding: const EdgeInsets.only(right: 16.0),
width: 260,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Menu'),
const ComicTheme(
child: Divider(
height: 24,
),
),
menu(
label: 'Home',
contentBuilder: () => const HomeContent(),
),
menu(
label: 'Comic Theme',
contentBuilder: () => const ComicScreenDemoScreen(),
),
menu(
label: 'Sleek Theme',
contentBuilder: () => const SleekScreenDemoScreen(),
),
menu(
label: 'Comic Login',
contentBuilder: () => const ComicLoginDemo(),
),
menu(
label: 'Sleek Login',
contentBuilder: () => const SleekLoginDemo(),
),
menu(
label: 'Comic Theme UI Widgets',
contentBuilder: () => const ComicThemeUiWidgetsScreen(),
),
menu(
label: 'Sleek Theme UI Widgets',
contentBuilder: () => const SleekThemeUiWidgetsScreen(),
),
const ComicTheme(
child: Divider(
height: 24,
),
),
menu(
label: 'Search Widget',
contentBuilder: () => const SearchScreen()),
menu(label: "AppBar", contentBuilder: () => const AppBarScreen()),
menu(label: 'Badge', contentBuilder: () => const BadgeScreen()),
menu(
label: 'BottomAppBar',
contentBuilder: () => const BottomAppBarScreen()),
menu(
label: 'BottomSheet',
contentBuilder: () => const BottomSheetScreen()),
menu(label: 'Buttons', contentBuilder: () => const ButtonsScreen()),
menu(label: 'Card', contentBuilder: () => const CardScreen()),
menu(
label: 'Checkbox',
contentBuilder: () => const CheckboxScreen()),
// menu(label: 'CheckboxListTile', contentBuilder: () => const CheckboxListTileScreen()),
menu(label: 'Chip', contentBuilder: () => const ChipScreen()),
menu(label: 'Dialog', contentBuilder: () => const DialogScreen()),
menu(label: 'Divider', contentBuilder: () => const DividerScreen()),
menu(
label: 'Dropdown',
contentBuilder: () => const DropdownScreen()),
menu(
label: 'Floating Action Button',
contentBuilder: () => const FloatingActionButtonScreen()),
menu(
label: 'IconButton',
contentBuilder: () => const IconButtonScreen()),
menu(
label: 'ListTile',
contentBuilder: () => const ListTileScreen()),
menu(
label: 'NavigationBar',
contentBuilder: () => const NavigationBarScreen()),
menu(
label: "NavigationDrawer",
contentBuilder: () => const NavigationDrawerScreen()),
menu(
label: 'NavigationRail',
contentBuilder: () => const NavigationRailScreen()),
menu(
label: 'Progress Indicator',
contentBuilder: () => const ProgressIndicatorScreen()),
menu(
label: 'Radio Button',
contentBuilder: () => const RadioButtonScreen()),
menu(
label: 'Segmented Button',
contentBuilder: () => const SegmentedButtonScreen()),
menu(
label: 'SnackBar',
contentBuilder: () => const SnackBarScreen()),
menu(label: 'Switch', contentBuilder: () => const SwitchScreen()),
menu(label: 'TabBar', contentBuilder: () => const TabBarScreen()),
menu(
label: 'TextFields',
contentBuilder: () => const TextFieldScreen()),
menu(
label: 'TextFormField',
contentBuilder: () => const TextFormFieldScreen()),
menu(
label: 'Toggle Button',
contentBuilder: () => const ToggleButtonScreen()),
const Text('Custom Theme Data:'),
const ComicTheme(
child: Divider(
height: 24,
),
),
menu(
label: 'ComicIconButtonThemeData',
contentBuilder: () => const ComicIconButtonThemeDataContent(),
),
menu(
label: 'SleekIconButtonThemeData',
contentBuilder: () => const SleekIconButtonThemeDataContent(),
),
menu(
label: 'ComicTextButtonThemeData',
contentBuilder: () => const ComicTextButtonThemeDataContent(),
),
const Text('Extensions:'),
const ComicTheme(
child: Divider(
height: 24,
),
),
menu(
label: 'ComicBorder',
contentBuilder: () => const ComicBorderScreen(),
),
const Text('Custom Widgets:'),
const ComicTheme(
child: Divider(
height: 24,
),
),
menu(
label: 'BirthdatePicker',
contentBuilder: () => const BirthdatePickerScreen()),
menu(
label: 'ComicListView',
contentBuilder: () => const ComicListViewScreen()),
menu(
label: 'SleekListView',
contentBuilder: () => const SleekListViewScreen()),
menu(label: 'Setting', contentBuilder: () => const SettingScreen()),
menu(
label: 'Basic Carousel Entry',
contentBuilder: () => const BasicCarouselEntryScreen()),
menu(
label: 'Wave Carousel Entry',
contentBuilder: () => const WaveCarouselEntryScreen()),
menu(
label: 'Round Carousel Entry',
contentBuilder: () => const RoundCarouselEntryScreen()),
menu(
label: 'Sleep Walker',
contentBuilder: () => const SleepWalkerScreen()),
menu(
label: 'Color scheme',
contentBuilder: () => const ColorSchemeScreen()),
menu(
label: 'Current theme config',
contentBuilder: () => const CurrentThemeScreen()),
],
),
),
);
}
menu({
required String label,
required Widget Function() contentBuilder,
}) {
return ListTile(
onTap: () {
EasyState.of<AppState>(context).setContent(contentBuilder());
showSideMenu = false;
setState(() {});
},
title: Text(
label,
style: const TextStyle(fontSize: 14),
),
);
}
}
更多关于Flutter设计系统插件easy_design_system的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter设计系统插件easy_design_system的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用easy_design_system
插件的一个代码示例。这个插件旨在帮助开发者快速创建和维护设计系统。我们将通过一个简单的例子展示如何集成和使用它。
首先,确保你已经在pubspec.yaml
文件中添加了easy_design_system
依赖:
dependencies:
flutter:
sdk: flutter
easy_design_system: ^最新版本号 # 请替换为实际发布的最新版本号
然后运行flutter pub get
来安装依赖。
接下来,我们来看如何在代码中使用easy_design_system
。
1. 创建主题
首先,我们需要定义一个主题。easy_design_system
允许我们定义颜色、字体、间距等。
import 'package:flutter/material.dart';
import 'package:easy_design_system/easy_design_system.dart';
final EasyDesignSystem theme = EasyDesignSystem(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.light,
),
textTheme: TextTheme(
headline1: TextStyle(fontSize: 32, color: Colors.black),
bodyText1: TextStyle(fontSize: 16, color: Colors.grey[600]!),
),
spacing: const Spacing(
unit: 8.0,
scale: 1.5,
),
);
2. 应用主题到应用
我们可以使用MaterialApp
的theme
属性来应用我们定义的主题。
void main() {
runApp(MyApp(theme: theme));
}
class MyApp extends StatelessWidget {
final EasyDesignSystem theme;
MyApp({required this.theme});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: theme.colorScheme,
textTheme: theme.textTheme,
),
home: MyHomePage(),
);
}
}
3. 使用主题中的元素
现在,我们可以在应用中使用主题中定义的元素,比如颜色和文本样式。
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final EasyDesignSystem theme = EasyDesignSystem.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Easy Design System Demo'),
theme: AppBarTheme(
color: themeData.colorScheme.primary,
textTheme: TextTheme(
headline6: theme.textTheme.headline1!.copyWith(color: themeData.colorScheme.onPrimary),
),
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Hello, Flutter!',
style: theme.textTheme.headline1,
),
SizedBox(height: theme.spacing.s16), // 使用主题中的间距
Text(
'This is a demo of easy_design_system.',
style: theme.textTheme.bodyText1,
),
],
),
),
);
}
}
4. 获取主题实例
在Flutter组件树的任何地方,你都可以通过EasyDesignSystem.of(context)
来获取当前主题实例。
// 示例:在另一个组件中获取主题
final EasyDesignSystem theme = EasyDesignSystem.of(context);
以上代码展示了如何在Flutter项目中使用easy_design_system
插件来定义和应用一个设计系统。这个插件极大地简化了主题的管理和应用,使得开发者可以更加专注于业务逻辑的实现。
请确保查阅easy_design_system
的官方文档以获取更多高级用法和最新功能。