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 提供了用于您的应用程序的启动屏幕。

基本轮播入口 波浪形轮播入口 圆形轮播入口
BasicCarouselEntry WaveCarouselEntry RoundCarouselEntry

示例

以下是 Easy Design System (SDS) 的一些示例。

漫画主题 简洁主题
DemoScreen DemoScreen
DemoScreen DemoScreen
DemoScreen DemoScreen
DemoScreen DemoScreen
DemoScreen DemoScreen

使用方法

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

1 回复

更多关于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. 应用主题到应用

我们可以使用MaterialApptheme属性来应用我们定义的主题。

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的官方文档以获取更多高级用法和最新功能。

回到顶部