热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用抽象工厂方法构建Flutter主题

image 老铁记得 转发 ,猫哥会呈现更多 Flutter 好文~~~~ 微信群 ducafecat b 站 https://space.bilibili.com/404904528
用抽象工厂方法构建 Flutter 主题
image

老铁记得 转发 ,猫哥会呈现更多 Flutter 好文~~~~

微信群 ducafecat

b 站 https://space.bilibili.com/404904528

原文

https://vbacik-10.medium.com/flutter-build-theme-with-abstract-factory-method-e07df8f730e2

代码

https://github.com/VB10/flutter-abstract-theme-manager

参考

  • https://zeplin.io

正文

最多的应用程序至少创建了一个主题。也许这对于第一个版本来说已经足够了,但是如果这个项目继续增长呢?让我们来看看怎么做。

我们知道项目设计的主题有多重要,所以我们将为项目创建一个主题管理器。让我们创建一个主题管理器以及这个购物页面。

用抽象工厂方法构建 Flutter 主题
image
  • 设计稿
    https://adobe.ly/xdfreshfooduikit

首先,它需要一个页面设计,如也这个页面可以连接到服务。(我为这个示例页面创建了这个端点)

  • Background 背景
  • App bar – 应用程式栏
  • Search Bar – 搜寻栏
    — Search Icon ー搜寻图示
    — Search Text ー搜寻文字
    — Microphone Icon ー麦克风图标
  • ListView
    — Product Card ー产品卡
  • TabBar
    — TabBar Icons ー TabBar 图标集

因此,我们需要一个调色板使用这个项目。如果你的设计工具包有一个调色板,你可以在设计工具包中得到所有的颜色。

用抽象工厂方法构建 Flutter 主题
image

项目必须在需要新小部件时使用这个调色板。实际上,由于有了主题经理,项目会更容易成长。最后,我们准备好了 Hacking 时间,因此我们将同时使用工厂方法模式和页面原子设计。

Hacking Time

首先,我更喜欢先写核心特性,这就是为什么我们不会在代码完成时加倍工作的原因:

  • 使用不同颜色和样式的 ITheme 抽象类
  • 用于从一个点管理不同主题的 ThemeFactory 类

工厂设计是创新模式之一。这个模式提供了高级对象,因为客户机什么都不知道。现在,该模式创建了一个自定义对象,以便项目可以使用这个方案。

用抽象工厂方法构建 Flutter 主题
image

现在我们知道了这个结构需要什么,因为我们可以编写一个同时包含文本和颜色的界面。这个接口提供了一个中心视点,因此项目需要。让我们写下这些要点。

文本主题界面

每个项目都需要这一点,因为大多数用法都指向项目的文本指南。所以我们创建基本样式指南后,非常容易从视图使用。有时我们需要自定义文本样式并不意味着你不使用当前的样式。我们可以使用 copyWith 函数,这样就可以像 headline5 一样使用视图,也可以添加自定义属性,如文本颜色。

abstract class ITextTheme {
  final Color? primaryColor;
  late final TextTheme data;
  TextStyle? headline1;
  TextStyle? headline3;
  TextStyle? headline4;
  TextStyle? headline5;
  TextStyle? headline6;
  TextStyle? subtitle1;
  TextStyle? subtitle2;
  TextStyle? bodyText1;
  TextStyle? bodyText2;
  String? fontFamily;

  ITextTheme(this.primaryColor);
}

如果您的项目设计有一个工具包,您可以使用 zeplin 工具。这个工具在样式指南选项卡中获取所有的文本样式。

https://zeplin.io/

用抽象工厂方法构建 Flutter 主题
image

颜色主题界面

指向项目是非常重要的,因为你知道颜色无处不在。所以我们如何管理更多的项目很容易控制。每个项目都有一个特定的颜色模式,您必须在代码中使用这个模式。如果你不使用模式和项目有一个静态的颜色代码,你不会添加多主题选项,另外你不能管理颜色问题。

abstract class IColors {
  _AppColors get colors;
  Color? scaffoldBackgroundColor;
  Color? appBarColor;
  Color? tabBarColor;
  Color? tabbarSelectedColor;
  Color? tabbarNormalColor;
  Brightness? brightness;

  ColorScheme? colorScheme;
}

我说像 paragraph 关于 zeplin。再次你可以使用这个和你能够所有的颜色属性。

用抽象工厂方法构建 Flutter 主题
image

Abstract Factory Manager

为多界面创建的管理器。此管理器将为项目创建 ThemeData 实例。由于这个接口,您可以创建一个新的主题实例。这个新的主题只需要一个配色方案等。

abstract class ITheme {
  ITextTheme get textTheme;
  IColors get colors;
}

是的,它看起来很简单,对任何项目都很有用。最后,我们准备使用核心主题绘制操作,因此项目可以声明这个结构的自定义主题。也许,这些主题接口可以改进得更高级。现在对于这个项目来说已经足够了。

最后需要工厂创建者和我们使用这个项目的主题管理器

abstract class ThemeManager {
  static ThemeData craeteTheme(ITheme theme) => ThemeData(
      fontFamily: theme.textTheme.fontFamily,
      textTheme: theme.textTheme.data,
      cardColor: theme.colors.colorScheme?.onSecondary,
      floatingActionButtonTheme: FloatingActionButtonThemeData(
          foregroundColor: theme.colors.colors.white,
          backgroundColor: theme.colors.colors.green),
      appBarTheme: AppBarTheme(backgroundColor: theme.colors.appBarColor),
      scaffoldBackgroundColor: theme.colors.scaffoldBackgroundColor,
      colorScheme: theme.colors.colorScheme);
}

我计划只有具体的领域,因为它的项目只有两个页面,因为你知道这个样本。你必须创建文本样式和配色方案区域的其他区域。让我们用这个结构创建自定义主题,我们将展示这种使用优势。

Ligh Theme on Project

实际上,我们有一个结构和项目,如何创建一个轻的主题。

class AppThemeLight extends ITheme {
  @override
  late final ITextTheme textTheme;

  AppThemeLight() {
    textTheme = TextThemeLight(colors.colors.mediumGrey);
  }

  @override
  IColors get colors => LightColors();
}

当然,暗主题创建这样,因此只是改变风格的指导方针和项目可以直接使用。您可以在这里访问黑暗主题代码。

TextTheme Light 需要绘制文本默认颜色的基本颜色,而浅色已经从 zeplin 样式创建。

class TextThemeLight implements ITextTheme {
  @override
  late final TextTheme data;

  @override
  TextStyle? bodyText1;

  @override
  TextStyle? bodyText2;

  @override
  TextStyle? headline1;

  @override
  TextStyle? headline3;

  @override
  TextStyle? headline4;

  @override
  TextStyle? headline5;

  @override
  TextStyle? headline6;

  @override
  TextStyle? subtitle1;

  @override
  TextStyle? subtitle2;
  final Color? primaryColor;

  TextThemeLight(this.primaryColor) {
    data = TextTheme(
      headline6: TextStyle(fontSize: 20, fontWeight: FontWeight.normal),
      subtitle1: TextStyle(fontSize: 16.0),
    ).apply(bodyColor: primaryColor);
    fOntFamily= GoogleFonts.arvo().fontFamily;
  }

  @override
  String? fontFamily;
}

好的,如果我们想看浅色的主题实例,它显示了这一点。

class LightColors implements IColors {
  @override
  final _AppColors colors = _AppColors();

  @override
  ColorScheme? colorScheme;
  @override
  Color? appBarColor;

  @override
  Color? scaffoldBackgroundColor;

  @override
  Color? tabBarColor;

  @override
  Color? tabbarNormalColor;

  @override
  Color? tabbarSelectedColor;

  LightColors() {
    appBarColor = colors.white;
    scaffoldBackgroundColor = colors.white;
    tabBarColor = colors.green;
    tabbarNormalColor = colors.lighterGrey;
    tabbarSelectedColor = colors.darkerGrey;
    colorScheme = ColorScheme.light()
        .copyWith(onPrimary: colors.green, onSecondary: colors.white);
    brightness = Brightness.light;
  }

  @override
  Brightness? brightness;
}

有时需要准备风格,因为没有足够的风格知识。这时你可以为你的项目使用一个配色方案实例,这样你就可以得到材质配色方案,因此可以添加你自定义的业务层。

而 Light 主题就是准备使用的。该项目只需要主题工厂方法,您可以编写这个类实例。对于项目颜色的所有内容,这都是可以接受的。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '@VB10',
      theme: ThemeManager.craeteTheme(AppThemeLight()),
      home: SampleView(),
    );
  }
}

是的,我们可以开始在搜索结果屏幕上绘图。特别是不要忘记这个方法,让我们看看如何为这个项目创建一个主题实例。

abstract class ThemeManager {
  static ThemeData craeteTheme(ITheme theme) => ThemeData(
      fontFamily: theme.textTheme.fontFamily,
      textTheme: theme.textTheme.data,
      cardColor: theme.colors.colorScheme?.onSecondary,
      tabBarTheme: TabBarTheme(
        indicator: BoxDecoration(),
        labelColor: theme.colors.tabbarSelectedColor,
        unselectedLabelColor: theme.colors.tabbarNormalColor,
      ),
      floatingActionButtonTheme: FloatingActionButtonThemeData(
          foregroundColor: theme.colors.colors.white,
          backgroundColor: theme.colors.colors.green),
      appBarTheme: AppBarTheme(backgroundColor: theme.colors.appBarColor),
      scaffoldBackgroundColor: theme.colors.scaffoldBackgroundColor,
      colorScheme: theme.colors.colorScheme);
}

现在项目直接依赖于所有的主题实例,因为我们只是改变主题值后,这个项目去一个新的配色方案,另外项目从来不需要任何代码的设计时间。这一点意味着你的项目设计已经完成了所有的工作

Feature Page

我们有一个主题实例,所以只需调用这个实例,一切就绪。首先,绘制页面树非常重要,更好地理解。

[图片上传失败…(image-a4213-1625618584460)]

现在编码非常简单,因为我们知道如何绘制这个。特别是您对编码时间非常注意,因此可以在页面设计中始终使用主题实例。该项目有一个主题设计,因为可以直接调用这个变量。例如,任何页面可以需要背景色,所以我们不需要一遍又一遍地写,因为我们有使用这种情况的主题实例。

[图片上传失败…(image-361204-1625618584460)]

是的,我们准备开发另外的主题管理器和小部件树结构。首先,让我们在编码中创建一个 tab 视图结构。

  final List> _pages = [
    MapEntry(SampleView(), Icons.search),
    MapEntry(Container(), Icons.search),
    MapEntry(Container(), Icons.search),
    MapEntry(Container(), Icons.search),
  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: _pages.length,
        child: Scaffold(
          floatingActionButtonLocation:
              FloatingActionButtonLocation.centerDocked,
          floatingActionButton: floatingActionButton(context),
          bottomNavigationBar: _bottomAppBar(),
          body: TabBarView(children: _pages.map((e) => e.key).toList()),
        ));
  }

实际上,我们看到了 fab 按钮,我们需要一个自定义颜色,因为这个颜色是为蓝色创建的,但是我们在主题中添加了这个自定义代码,只写了一个浮动的操作按钮。此按钮从上下文中读取主题实例中的 own 属性。

[图片上传失败…(image-837c1f-1625618584460)]

我说你不需要额外的代码,直接调用这个小部件。

FloatingActionButton floatingActionButton(BuildContext context) {
  return FloatingActionButton(
    child: Icon(Icons.add),
    onPressed: () {},
  );
}

之后,让我们显示搜索结果页面设计。我们谈到了这篇页面设计对文章的打击。这对颤振计划非常重要。你需要一直考虑这个树型结构。你可以用这个小部件树的思想做一个很棒的页面。

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: buildAppBar(context),
      body: Padding(
        padding: EdgeInsets.only(top: MediaQuery.of(context).size.width * 0.08),
        child: Column(
          children: [
            textFieldSearchCard(context),
            Expanded(child: buildGridViewBody()),
          ],
        ),
      ),
    );
  }

这说明了很多问题。让我们来看一些小部件,以了解如何使用主题。我们的设计有一个自定义搜索栏,带有搜索图标和麦克风按钮。

Widget textFieldSearch(BuildContext context) {
 return TextField(
 decoration: InputDecoration(
 border: InputBorder.none,
 prefixIcon: Icon(Icons.search_sharp,
 color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.5)),
 suffixIconConstraints: BoxConstraints(maxHeight: 30),
 suffixIcon: FloatingActionButton(
 onPressed: () {},
 mini: true,
 child: Icon(Icons.mic_sharp),
)),
);
}

这种代码设计不需要额外的代码。您可以从主题上下文中使用这里需要的内容。让我们来看看文本样式示例:

Text buildTextSub(BuildContext context) {
  return Text(
    items.searchResults,
    style:Theme.of(context).textTheme.headline6?.copyWith(
      letterSpacing: -0.2,
      fontWeight: FontWeight.w400,
      ),
  );
}

你可以看到这是一个非常简单和易于管理的代码,我只是添加了一些自定义代码并完成了所有的工作。

你可以看到条目属性,也许这和注释有重要的关系。如果您拥有所有的常量值类,并且只想创建常量值,那么您可以在类获得安全能力之后添加@immutable 注释。

@immutable
class AppTextItems {
  final String searchResults = 'Search Results';
  final String brocoliText = 'Broccoli';
}

是的,这个项目可能是理解这个体系结构的一个样本,但是总是应该编写强大的代码。

Yees 项目已经完成。如果你想改变一个主题,比如黑暗,我们只需要把这个实例改成黑暗,然后就可以了。

[图片上传失败…(image-5f4c53-1625618584460)]

因此,我们采用了抽象的工厂设计能力和可管理的代码设计。它听起来很适合开发力量,因为颤振可以改善模式和特殊的角度。

用抽象工厂方法构建 Flutter 主题
image

完成了。现在我们可以直接实施我们自己的项目并管理一切。另一方面,这个项目不需要如何创建新的主题知识,因为你知道我们创建接口。不同的主题刚好适合这些界面,然后一切都完成了。

实际上,本文的主要目标是如何在主题实例中使用这种模式,因此这方面的知识对您的开发生活非常重要。

感谢你阅读《感谢你阅读《为你的生命健康》》

https://github.com/VB10/flutter-abstract-theme-manager


© 猫哥

https://ducafecat.tech/

https://github.com/ducafecat

往期

开源

GetX Quick Start

https://github.com/ducafecat/getx_quick_start

新闻客户端

https://github.com/ducafecat/flutter_learn_news

strapi 手册译文

https://getstrapi.cn

微信讨论群 ducafecat

系列集合

译文

https://ducafecat.tech/categories/%E8%AF%91%E6%96%87/

开源项目

https://ducafecat.tech/categories/%E5%BC%80%E6%BA%90/

Dart 编程语言基础

https://space.bilibili.com/404904528/channel/detail?cid=111585

Flutter 零基础入门

https://space.bilibili.com/404904528/channel/detail?cid=123470

Flutter 实战从零开始 新闻客户端

https://space.bilibili.com/404904528/channel/detail?cid=106755

Flutter 组件开发

https://space.bilibili.com/404904528/channel/detail?cid=144262

Flutter Bloc

https://space.bilibili.com/404904528/channel/detail?cid=177519

Flutter Getx4

https://space.bilibili.com/404904528/channel/detail?cid=177514

Docker Yapi

https://space.bilibili.com/404904528/channel/detail?cid=130578


推荐阅读
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 在探讨如何在Android的TextView中实现多彩文字与多样化字体效果时,本文提供了一种不依赖HTML技术的解决方案。通过使用SpannableString和相关的Span类,开发者可以轻松地为文本添加丰富的样式和颜色,从而提升用户体验。文章详细介绍了实现过程中的关键步骤和技术细节,帮助开发者快速掌握这一技巧。 ... [详细]
  • 在C#编程中,设计流畅的用户界面是一项重要的任务。本文分享了实现Fluent界面设计的技巧与方法,特别是通过编写领域特定语言(DSL)来简化字符串操作。我们探讨了如何在不使用`+`符号的情况下,通过方法链式调用来组合字符串,从而提高代码的可读性和维护性。文章还介绍了如何利用静态方法和扩展方法来实现这一目标,并提供了一些实用的示例代码。 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • Unity3D 中 AsyncOperation 实现异步场景加载及进度显示优化技巧
    在Unity3D中,通过使用`AsyncOperation`可以实现高效的异步场景加载,并结合进度条显示来提升用户体验。本文详细介绍了如何利用`AsyncOperation`进行异步加载,并提供了优化技巧,包括进度条的动态更新和加载过程中的性能优化方法。此外,还探讨了如何处理加载过程中可能出现的异常情况,确保加载过程的稳定性和可靠性。 ... [详细]
  • 本文深入解析了WCF Binding模型中的绑定元素,详细介绍了信道、信道管理器、信道监听器和信道工厂的概念与作用。从对象创建的角度来看,信道管理器负责信道的生成。具体而言,客户端的信道通过信道工厂进行实例化,而服务端则通过信道监听器来接收请求。文章还探讨了这些组件之间的交互机制及其在WCF通信中的重要性。 ... [详细]
  • 体积小巧的vsftpd与pureftpd Docker镜像在Unraid系统中的详细配置指南:支持TLS加密及IPv6协议
    本文详细介绍了如何在Unraid系统中配置体积小巧的vsftpd和Pure-FTPd Docker镜像,以支持TLS加密和IPv6协议。通过这些配置,用户可以实现安全、高效的文件传输服务,适用于各种网络环境。配置过程包括镜像的选择、环境变量的设置以及必要的安全措施,确保了系统的稳定性和数据的安全性。 ... [详细]
  • 2018 HDU 多校联合第五场 G题:Glad You Game(线段树优化解法)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356在《Glad You Game》中,Steve 面临一个复杂的区间操作问题。该题可以通过线段树进行高效优化。具体来说,线段树能够快速处理区间更新和查询操作,从而大大提高了算法的效率。本文详细介绍了线段树的构建和维护方法,并给出了具体的代码实现,帮助读者更好地理解和应用这一数据结构。 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 在Java编程中,初始化List集合有多种高效的方法。本文介绍了六种常见的技术,包括使用常规方式、Arrays.asList、Collections.addAll、Java 8的Stream API、双重大括号初始化以及使用List.of。每种方法都有其特定的应用场景和优缺点,开发者可以根据实际需求选择最合适的方式。例如,常规方式通过直接创建ArrayList对象并逐个添加元素,适用于需要动态修改列表的情况;而List.of则提供了一种简洁的不可变列表初始化方式,适合于固定数据集的场景。 ... [详细]
  • 在PHP中实现腾讯云接口签名,以完成人脸核身功能的对接与签名配置时,需要注意将文档中的POST请求改为GET请求。具体步骤包括:使用你的`secretKey`生成签名字符串`$srcStr`,格式为`GET faceid.tencentcloudapi.com?`,确保参数正确拼接,避免因请求方法错误导致的签名问题。此外,还需关注API的其他参数要求,确保请求的完整性和安全性。 ... [详细]
author-avatar
odoresampey_768
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有