【Flutter 工程】005-代码分离实践:flutter_hooks functional_widget

news2024/11/28 22:47:42

【Flutter 工程】005-代码分离实践:flutter_hooks & functional_widget

文章目录

  • 【Flutter 工程】005-代码分离实践:flutter_hooks & functional_widget
  • 一、概述
    • 1、Flutter “嵌套地狱”
    • 2、代码分离实践
  • 二、实践
    • 1、安装 flutter_hooks & functional_widget
    • 2、代码示例
    • 3、生成代码
      • 命令
      • 生成的代码
    • 4、运行结果

一、概述

1、Flutter “嵌套地狱”

在Flutter开发中,“嵌套地狱”(Nesting Hell)是指在构建复杂的UI布局时,由于多层嵌套的组件结构,代码变得冗长、难以维护和理解的情况。

Flutter使用组件树的方式来构建用户界面,每个UI元素都是一个组件,可以包含其他组件。在某些情况下,特别是当需要实现复杂的布局或嵌套的组件结构时,代码中的组件嵌套层级可能会不断增加,从而导致出现"嵌套地狱"。

"嵌套地狱"可能会带来以下问题:

  1. 代码冗长和可读性差:过多的嵌套会导致代码变得冗长,难以理解和维护。每个嵌套层级都需要处理相应的组件和属性,使得代码结构复杂化。
  2. 性能问题:过多的嵌套可能会导致渲染性能下降。每个嵌套层级都需要进行布局计算和绘制操作,增加了渲染的负担。
  3. 调试和排查问题困难:当出现UI问题或错误时,由于嵌套层级较多,定位问题可能会变得更加困难。调试和排查错误所需的时间和精力也会增加。

为了避免"嵌套地狱",可以考虑以下策略:

  1. 抽取可复用的组件:将复杂的UI部分拆分为独立的可复用组件,使代码更加模块化和清晰。这样可以减少嵌套层级,并使代码更易读和维护。
  2. 使用布局组件:Flutter提供了各种布局组件(如Row、Column、Stack等),可以帮助管理UI布局。合理使用这些布局组件可以减少嵌套层级,并简化布局代码。
  3. 使用状态管理工具:对于具有复杂交互和状态管理的应用,使用适当的状态管理工具(如Provider、Bloc等)可以减少嵌套层级,并更好地组织和管理应用的状态和逻辑。
  4. 审视UI设计和交互需求:在设计UI和交互时,尽量避免过于复杂和深层次的嵌套结构,简化UI布局和交互流程,以提高代码的可读性和维护性。

2、代码分离实践

结合 flutter_hooks & functional_widget 两个库实现代码分离。

参考文章:

【Flutter 工程】003-钩子函数:Flutter Hooks

https://blog.csdn.net/qq_29689343/article/details/130885106

【Flutter 工程】004-代码生成:functional_widget

https://blog.csdn.net/qq_29689343/article/details/130887815

用一种更有条理的方法写Flutter代码——使用Flutter Hooks与函数式组件

https://blog.csdn.net/qq_50101967/article/details/128688448

二、实践

1、安装 flutter_hooks & functional_widget

# 安装 flutter_hooks
flutter pub add flutter_hooks

# 安装 functional_widget
flutter pub add dev:functional_widget dev:build_runner functional_widget_annotation

2、代码示例

方法是否以$开头有自己决定!

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:functional_widget_annotation/functional_widget_annotation.dart';

part 'main.g.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

/// 视图代码
class MyHomePage extends HookWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  
  Widget build(BuildContext context) {
    final counter = Counter.use(0);
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const $OnlyText('You have pushed the button this many times:'),
            $TextWithStyle('${counter.value}'),
            $AddButton(counter.inc),
            $DecButton(counter.dec),
          ],
        ),
      ),
    );
  }
}

/// 逻辑代码
class Counter {
  static use(initialValue) {
    return Counter().._count = useState(initialValue);
  }

  late final ValueNotifier<int> _count;

  get value => _count.value;

  inc() {
    _count.value++;
  }

  dec() {
    _count.value--;
  }
}

/// 样式代码

Widget $onlyText(String text) {
  return Text(text);
}


Widget $textWithStyle(BuildContext context, String text) {
  return Text(
    text,
    style: Theme.of(context).textTheme.headlineLarge,
  );
}


Widget $addButton(final VoidCallback? onPressed) {
  return FloatingActionButton(
    onPressed: onPressed,
    tooltip: 'Increment',
    child: const Icon(Icons.add),
  );
}


Widget $decButton(final VoidCallback? onPressed) {
  return FloatingActionButton(
    onPressed: onPressed,
    tooltip: 'Decrement',
    child: const Icon(Icons.minimize),
  );
}

3、生成代码

命令

# --delete-conflicting-outputs 可选,会在生成代码冲突的时候,删除原来的代码,重新生成
flutter pub run build_runner build --delete-conflicting-outputs

生成的代码

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'main.dart';

// **************************************************************************
// FunctionalWidgetGenerator
// **************************************************************************

/// 样式代码
class $OnlyText extends StatelessWidget {
  /// 样式代码
  const $OnlyText(
    this.text, {
    Key? key,
  }) : super(key: key);

  /// 样式代码
  final String text;

  
  Widget build(BuildContext _context) => $onlyText(text);
}

class $TextWithStyle extends StatelessWidget {
  const $TextWithStyle(
    this.text, {
    Key? key,
  }) : super(key: key);

  final String text;

  
  Widget build(BuildContext _context) => $textWithStyle(
        _context,
        text,
      );
}

class $AddButton extends StatelessWidget {
  const $AddButton(
    this.onPressed, {
    Key? key,
  }) : super(key: key);

  final void Function()? onPressed;

  
  Widget build(BuildContext _context) => $addButton(onPressed);
}

class $DecButton extends StatelessWidget {
  const $DecButton(
    this.onPressed, {
    Key? key,
  }) : super(key: key);

  final void Function()? onPressed;

  
  Widget build(BuildContext _context) => $decButton(onPressed);
}

4、运行结果

image-20230526160133811

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/572675.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

油猴脚本尝试

现在是这样的&#xff0c;我这边有个运维系统&#xff0c;里面有个日志&#xff0c;我们经常要复制&#xff0c;然后我们复制的时候需要打开内容&#xff0c;然后去选中复制。 类似于这种&#xff0c;我觉得这个时候&#xff0c;去选中复制就很麻烦&#xff0c;右边这里不是有…

ChatGPT四大基本使用场景分析

ChatGPT是一种基于深度神经网络的自然语言生成模型&#xff0c;它能够通过大量的数据训练和学习&#xff0c;以模拟人类的自然语言交互方式来理解和回答用户提出的问题。作为一种全新的人工智能技术&#xff0c;ChatGPT具有高度的灵活性和可扩展性&#xff0c;可以不断地优化、…

Redis BigKey问题

1.广告平台,海量数据查询固定前缀的key 不要使用keys , 使用 scan 命令 scan 0 match "user:" 10 2.Memory usage命令用过吗 memory usage key [semples count] :计算每个键值对的字节数 3.bigKey 问题&#xff0c;多大算bigKey,如何发现&#xff1f;如何处理?如…

【Linux】打开Linux大门,踏入Linux世界(环境搭建再加一群Linux基本指令就OK啦~)

&#x1f9d1;‍&#x1f393;个人主页&#xff1a;简 料 &#x1f3c6;所属专栏&#xff1a;Linux系统编程与网络编程 &#x1f3c6;个人社区&#xff1a;越努力越幸运社区 &#x1f3c6;简 介&#xff1a;简料简料&#xff0c;简单有料~在校大学生一枚&#x…

论文分享 | 视野约束下多机器人系统的最小持久图生成与编队控制

阿木推出的Prometheus项目校园赞助活动&#xff0c;再次迎来开发者参与&#xff01; 北京理工大学自动化学院赵欣悦同学&#xff0c;在Prometheus开源仿真架构的基础上进行了二次开发&#xff0c;且使用P450进行了真机实验并发表了相关论文&#xff0c;其论文《视野约束下多机…

前端开发如何速成java,使用java开发网络接口

引言 我是干前端的&#xff0c;闲来没事&#xff0c;也想学学java&#xff0c;下面我会根据我学习java的经历来整理出java的速成之路。 学习路线 按照数字的顺序学下去就行了 1.学习java基础教程&#xff1a;主要听 class和集合这两部分吧&#xff0c;这两个部分非常重要&am…

ASEMI代理韩景元可控硅C106M参数,C106M封装,C106M尺寸

编辑-Z 韩景元可控硅C106M参数&#xff1a; 型号&#xff1a;C106M 断态重复峰值电压VDRM&#xff1a;600V 通态电流IT(RMS)&#xff1a;4A 通态浪涌电流ITSM&#xff1a;30A 平均栅极功耗PG(AV)&#xff1a;0.2W 峰值门功率耗散PGM&#xff1a;1W 工作接点温度Tj&…

【LeetCode】《LeetCode 101》第九章:巧解数学问题

文章目录 9.1 公倍数与公因数9.2 质数204.计数质数&#xff08;中等&#xff09; 9.3 数字处理504. 七进制数&#xff08;简单&#xff09;172. 阶乘后的零&#xff08;中等&#xff09;415. 字符串相加&#xff08;简单&#xff09;326. 3 的幂&#xff08;简单&#xff09; 9…

mysql语句最大执行时间问题解决,无需改mysql配置

下面是我排错的一个过程&#xff1a; 1、我是ado.net执行一个查询语句报了个错&#xff1a; Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 译&#xff1a;超时已过期。操作完成前经过的超时时间&a…

【Netty】 工作原理详解(十一)

文章目录 前言一、Netty 模型二、代码示例2.1、引入Maven依赖2.2、服务端的管道处理器2.3、服务端主程序2.4、客户端管道处理器2.5、客户端主程序2.6、测试运行 总结 前言 回顾Netty系列文章&#xff1a; Netty 概述&#xff08;一&#xff09;Netty 架构设计&#xff08;二&…

借军工经验开拓消费市场,三星显示收购eMagin浅析

前不久三星显示&#xff08;Samsung Display&#xff09;宣布&#xff0c;拟支付2.18亿美元收购微显示方案商eMagin全部普通股&#xff0c;收购完成后eMagin将并入三星显示&#xff0c;以加速XR显示业务发展。 据青亭网了解&#xff0c;eMagin成立于1996年&#xff0c;该公司多…

《Spring Guides系列学习》guide11 - guide15

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gu…

JVM调优实战

1、当项目运行一段时间以后&#xff0c;产生了OOM的问题&#xff0c;我们该如何排查问题呢&#xff1f; 用top命令&#xff0c;看看是哪个进程CPU占用率高&#xff0c;获取它的进程ID&#xff0c;再根据具体的进程id&#xff0c;执行 top -HP 进程id号 命令,看看哪个线程的CP…

复制架构,Redis Sentinel分析

存储高可用&#xff0c;一般采用复制架构&#xff0c;复制架构&#xff0c;需要关注故障架构和状态决策2个要点 复制架构通用关注点 数据复制 复制格式 格式优点缺点举例命令数据量小可能存在数据不一致Mysql 的statement同步方式&#xff0c;按commit顺序同步&#xff0c;…

文件系统考古:1974-Unix V7 File System

有时&#xff0c;进步难以察觉&#xff0c;特别是当你正身处其中时。而对比新旧资料之间的差异&#xff0c;寻找那些推动变革的信息源&#xff0c;我们就可以清晰地看到进步的发生。在Linux&#xff08;以及大部分Unix系统&#xff09;中&#xff0c;都可以印证这一点。 Unix …

淘宝层级改版,五力模型上线!

最近临近618&#xff0c;淘系又各种功能改版&#xff0c;现在店铺层级也开始陆续改版了。从原来的只需要提升销售金额&#xff0c;到现在的五力模型。我们先说一下原来的店铺层级考核&#xff0c;跟现在的区别主要是哪&#xff1f; 1.原来店铺层级的考核升级特别简单&#xff0…

推荐一款神级编程工具[Cursor]自带gpt而且免费!

今天推荐一款非常好用开发工具&#xff0c;一个智能编程助手。 官网&#xff1a;https://www.cursor.so/ 适用平台&#xff1a;Mac、Windows、Linux。 助手的样子 可以做哪些事情&#xff1f; 编程语言&#xff1a;我可以回答关于各种编程语言&#xff08;如Python、Java、Ja…

测试老鸟总结,从功能到自动化测试详细整理,测试之路广阔无垠...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

黑客零基础入门教程,从入门到精通学习路线规划,看完这篇就够了

很多人上来就说想学习黑客&#xff0c;但是连方向都没搞清楚就开始学习&#xff0c;最终也只是会无疾而终&#xff01;黑客是一个大的概念&#xff0c;里面包含了许多方向&#xff0c;不同的方向需要学习的内容也不一样。 想要成为黑客&#xff0c;却苦于没有方向&#xff0c;…

戏曲APP软件开发需具备哪些功能呢?

戏曲是我国的国粹&#xff0c;传统戏曲文化源远流长&#xff0c;博大精深&#xff0c;数千年以来一直都是深受大众喜欢的文化生活的重要环节。随着时代的推进&#xff0c;娱乐形式更加多样化&#xff0c;传统的剧场演出形式的戏曲传播方式已经跟不上时代发展以及人们的需求了。…