Flutter 自定义组件的最佳实践

发布于:2024-10-24 编辑:匿名 来源:网络

我已经使用 Flutter 一段时间了,并使用 Flutter 做了一些演示项目。我也阅读了一些Flutter的源码,对Flutter的组件系统有了一些了解。

这里总结了 Flutter 自定义组件的最佳实践。最佳实践。

在Flutter上开发自定义组件其实有两种方式,一种是继承StatelessWidget或者StatefulWidget,另一种是使用RenderObject。继承StatelessWidget或StatefulWidget是最常用的方式,因为它们提供了一些现成的方法和属性,可以轻松实现组件生命周期和状态管理。

使用RenderObject时,需要自己实现一些方法和属性,比较复杂,一般用于实现一些复杂的自定义组件。我们分别看一下这两个方法的实现。

1、继承StatelessWidget或StatefulWidget 继承StatelessWidget或StatefulWidget是最常用的方式,因为它们提供了一些现成的方法和属性,可以方便地实现组件生命周期和状态管理。下面是一个实现 Counter 组件的简单示例。

该组件可以显示一个计数器,用户可以单击按钮来增加计数器值。代码语言:javascript copy class Counter extends StatefulWidget { @override _CounterState createState() => _CounterState();} class _CounterState extends State { int _count = 0; } void _increment() { setState(() { _count++; }) ; } @override Widget build(BuildContext context) { return Column( Children: [ Text('Count: $_count'), ElevatedButton( onPressed: _increment, child: Text(' Increment'),????? ),????????????????);???????????????????????????????????在这个例子中,我们定义了一个Counter组件,它继承于StatefulWidget,并实现了一个_CounterState类,它继承于State,用于管理组件的状态。

在_CounterState类中,我们定义了一个_count变量来保存计数器值,并定义了一个_increment方法来递增计数器值。在构建方法中,我们使用 Column 组件来显示计数器值和一个按钮,用户可以单击该按钮来增加计数器值。

2、使用RenderObject 使用RenderObject是一种更底层的方式,它可以让我们更加灵活地控制组件的布局和绘制。下面通过一个简单的例子来实现一个可以显示当前时间的时钟组件。

代码语言:javascript 复制 import ‘dart:async’;import ‘dart:math’ as math;import ‘package:flutter/material.dart’;class Clock 扩展 SingleChildRenderObjectWidget {??Clock({Widget child})?:?super(child: child );??@override??RenderObject?createRenderObject(BuildContext?context)?{????return?RenderClock();??}}类 RenderClock 扩展了 RenderBox {??DateTime?_dateTime?=?DateTime.now();??计时器_timer;??RenderClock()?{????_timer?= Timer.periodic(Duration(秒: 1),?(Timer t)?{??????_dateTime?=?DateTime.now();??????this.markNeedsPaint();????});??}??@override??void?performLayout()?{????尺寸?=?Size(,?);??}??@override??void?paint(PaintingContext?context,?Offset?offset)?{????final?Paint?paint?=?Paint()??????..color?=?Colors.black??????..style?=?PaintingStyle.lines??????..StrokeWidth?= 2.0;????最终中心= size.center(offset);????最终半径 = size.shortestSide / 2;????context.canvas.drawCircle(中心,半径,油漆);????// 绘制 h我们的手。????最终小时手长度=半径*0.5;????最终小时手弧度=((_dateTime.hour%12)+_dateTime.min/60)*2*math.pi/12-math.pi/2;????context.canvas.drawLine(??????center,??????Offset(center.dx?+?hourHandLength?*?math.cos(hourHandRadians),?????????????center.dy?+?hourHandLength?*?math.sin(hourHandRadians)),??????paint..行程宽度?= 6.0,????);????// 绘制分针。

????最终分钟手长度=半径*0.8;????最终分钟手弧度=(_dateTime.分钟+_dateTime.秒/60)*2*math.pi/60-math.pi/2;????context.canvas.drawLine(??????center,??????Offset(center.dx?+ 分钟HandLength?* math.cos(minuteHandRadians),?????????????center.dy?+ 分钟HandLength?*?math.sin(minhHandRadians)),??????paint..StrokeWidth?= 4.0,????);????// 绘制秒针。????最终第二手长度=半径*0.9;????最终 SecondHandRadians = _dateTime.second * 2 * math.pi / 60 - math.pi / 2;????context.canvas.drawLine(??????cent呃,偏移(center.dx + secondaryHandLength * math.cos(secondHandRadians),center.dy + secondaryHandLength * math.sin(secondHandRadians)),paint..color = Colors.red..StrokeWidth = 2.0,); } @override void detach() { _timer.cancel();超级.分离(); }} 效果如下图所示: 图0 上面的图0给出了两个实现自定义组件的例子。

第一种方式是继承 StatelessWidget 或 StatefulWidget,第二种方式是使用 RenderObject。在实际开发中,我们可能需要遵循一些最佳实践来提高组件的性能和可维护性。

这里主要讲组件封装、布局和文档。 1.组件封装 在flutter中,组件封装是很常见的。

虽然大多数时候flutter的组件库已经提供了我们需要的组件,但是有时候我们还是需要自定义一些组件来满足我们的需求。在封装组件时,我们应该遵循以下原则: ? 单一责任原则:一个组件只负责一个功能,不要将多个功能耦合在一个组件中。

? 高内聚和低耦合:组件内的各个部分应具有高内聚性,不同组件之间应具有低耦合性。 ? 易用性:组件的使用应该尽可能简单,用户不应该花费太多的时间和精力学习如何使用组件。

? 可定制性:组件应具有一定程度的可定制性,可以根据用户的需求进行定制。 ? 易于扩展:组件应具有一定的扩展性,能够方便地扩展新功能。

接下来我们举一个简单的例子。例如,我们想要实现一个日历组件,可以显示当月的日历并选择日期。

我们可以将这个日历组件封装成一个Calendar组件,该组件可以接受一个DateTime类型的参数来指定当前月份的日期。此日历组件可以包含 MonthView 组件和 WeekView 组件。

MonthView组件用于显示当月的日历,WeekView组件用于显示星期几。这样我们就将日历组件封装成了Calendar组件。

用户只需要传入一个DateTime类型的参数就可以使用这个日历组件。下面我看看如何按照上述原则来封装这个日历组件。

代码语言: javascript copy class Calendar extends StatelessWidget { Final DateTime date;日历({this.date}); @override Widget build(BuildContext context) { return Column( Children: [ MonthView(date: date), WeekView( ), ] , ); }}类 MonthView 扩展 StatelessWidget { 最终 DateTime 日期; MonthView({this.date}); @override Widget build(BuildContext context) { return Container( child: Text('月视图'), ); }}类 WeekView 扩展 StatelessWidget { @override Widget build(BuildContext context) { return Container( child: Text('Week View'), );我们来看看上述原则在这个例子中的应用:单一职责原则(Calendar、MonthView和WeekView各负责一个功能)、高内聚低耦合(Calendar组件由MonthView和WeekView组成,但它们之间的耦合度很低)、易用性(使用Calendar组件,只需要传入一个DateTime参数即可)、可定制灵活性(可以通过修改MonthView和WeekView的实现来定制组件的性能) )和可扩展性(可以通过添加更多子组件来扩展日历组件的功能)。2. 组件的布局 良好的布局可以提高组件的性能和用户体验。

有些组件需要从一开始就考虑响应式布局,这样才能适应不同的屏幕尺寸和分辨率。在布局组件时,应遵循以下原则: 灵活性:组件的布局应具有一定的灵活性,能够适应不同的屏幕尺寸和分辨率。

? 性能:组件的布局应尽可能简单,没有过多的嵌套和无用的布局。 ? 响应能力:组件的布局应该能够响应并根据屏幕尺寸和分辨率进行调整。

? 可访问性:组件的布局应具有一定程度的可访问性,以便用户轻松交互。接下来,我们来看另一个例子。

现在大家都喜欢玩大型语言模型的聊天对话应用,需要同时支持图片和文字。我们可以封装一个ChatMessage组件,它可以显示用户发送的消息。

它可以是文字或图片。该ChatMessage组件可以包括TextMessage组件和ImageMes??sage组件。

TextMessage 组件用于显示文本消息,ImageMes??sage 组件用于显示图片消息。这样我们就将聊天消息组件封装成了一个ChatMessage组件。

用户只需要传入一个Message对象就可以使用这个聊天消息组件。下面我就按照上面的原则来看看如何布局这个聊天消息组件。

代码语言:javascript复制类ChatMessage扩展StatelessWidget{最终Message消息;??ChatMessage({this.message});??@override??Widget?build(BuildContext?context)?{????return?Flexible(??????child:?message.type?==?MessageType.text????????????TextMessage(text:?message.text)??????????:?ImageMes??sage(image:?message.image),????);??}}类 TextMessage 扩展 StatelessWidget { 最终字符串文本;??TextMessage({this.text});??@override??Widget?build(BuildContext?context)?{????return?Semantics(??????child:?Text(text),??????label:?'短信',????);??}}类 ImageMes??sage 扩展 StatelessWidget { 最终字符串图像;??ImageMes??sage({this.image});??@override??Widget?build(BuildContext?context)?{????return?Semantics(??????child:?Image.network(image),??????label:?'图像消息',????);??}}在这个例子中,ChatMessage组件使用了灵活来自动调整其大小,以适应不同的屏幕尺寸和分辨率(灵活和响应方式)。同时,我们避免了不必要的预留和容器使用,另外,我们使用了语义组件来提供辅助功能,以提高可访问性。

3.组件的文档 当一个组件开发完成后,我们应该为该组件编写文档,以便其他开发人员能够快速了解??该组件的用法和功能。没有文档,没有人敢使用组件。

现在的开发者太懒了,不愿意花太多的时间和精力去学习如何使用组件。在编写组件文档时,我们应该遵循以下原则:? 简洁明了:文档应该简洁明了,不应该包含太多废话和无用的信息。

? 示例代码:文档应包含示例代码,以便开发人员能够快速了解??组件的用法。 ? 参数说明:文档中应包含参数说明,以便开发人员了解组件的参数和功能。

? 返回值描述:文档应包含返回值描述,以便开发人员能够了解组件的返回值和功能。 ? 效果演示:文档中应包含效果演示,以便开发人员了解组件的效果和功能。

今天就讲到这里,希望对大家有帮助。

Flutter 自定义组件的最佳实践

站长声明

版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。

标签:

相关文章

  • 快途物流完成1亿元B轮融资,中为资本、碧桂园创投等参与,

    快途物流完成1亿元B轮融资,中为资本、碧桂园创投等参与,

    据投资界4月7日消息,据36氪快途物流近期完成A轮融资由中维资本和碧桂园创投VC基金领投的融资。 参与投资的B轮融资金额约2亿元,奥拓投资、创新工场等老股东持续投资。 新一轮融资将主要用于全国市场拓展、产品升级和技术研发三个方面。 快途物流成立于今年8月。 是为中小企业

    06-18

  • 2019:技术为王

    2019:技术为王

    2019年:技术为王 2019年,中国互联网行业发展迎来重大转折。 一方面,基于中国网民数量增长趋向饱和的事实,所谓流量红利时代已经彻底结束,增量市场转变为存量市场,企业的生存和发展面临严峻挑战。 也遇到了很多困难。 另一方面,在移动互联网全面普及的背景下,互联网正以

    06-18

  • 身家暴涨250亿,何小鹏正在悄悄做LP

    身家暴涨250亿,何小鹏正在悄悄做LP

    除了造汽车,很少有人知道何小鹏的LP领地。 已经实现财务自由的何小鹏,依然是隐形的LP大佬。 所谓LP(Limited Partners),即有限合伙人,俗称“金融家之父”,是风险投资机构的投资者。 除了制造汽车之外,何小鹏还开始了LP。 如今,何小鹏的LP版图正在逐渐成型:通过上海

    06-17

  • 全球融资周报(11.27-12.3)

    全球融资周报(11.27-12.3)

    一周快速回顾: 1、巨头投资 1、新光益获得比亚迪投资。 近日,比亚迪完成对新广益的投资,成为第三大股东。 新光益是高性能特种功能材料开发商,服务于FPC、TP、汽车、医疗等行业。 目前,其主要客户为苹果、华为、OPPO等全球知名企业。 其主要产品有防溢胶特种膜、强力粘合

    06-18

  • 一站式综合物流服务商宅急送完成10亿元B轮融资

    一站式综合物流服务商宅急送完成10亿元B轮融资

    投资圈(ID:pedaily)据4月14日消息,宅急送集团宣布再获近人民币B轮投资1十亿。 本轮融资由远洋集团旗下远洋资本领投,宁波瀚润、高林资本等跟投。 宅急送继去年获得12亿元A轮融资后,再次获得产业资本的持续投资。 据了解,宅九配送公司成立于2007年,是一家有效整合物流、

    06-18

  • 当演唱会成为顶级带货主播的标配,意味着什么?刚刚在双11被称为低俗带货的

    当演唱会成为顶级带货主播的标配,意味着什么?刚刚在双11被称为低俗带货的

    肖央,转身办了一场演唱会。 近日,肖央歌举办的“肖央选星演唱会”邀请了肖央、张信哲、詹文婷、朴树、汪苏泷、钟欣潼、蔡卓妍等明星前来捧场。 此前,杨哥表示:举办演唱会的主要目的是回馈歌迷的支持。 不仅不卖货,还准备了数十辆电瓶车、手机、冰箱、平板电脑等高端礼品

    06-18

  • 国家普洛斯绿色能源投资平台设立完成,预计总投资规模近200亿

    国家普洛斯绿色能源投资平台设立完成,预计总投资规模近200亿

    8月8日,普洛斯投资及资产管理平台普洛斯资本GCP宣布完成设立国家GLP绿色能源投资平台。 预计资本规模约40亿元,投资方包括国家绿色发展基金、国家能源集团绿色低碳基金。 这是普洛斯与国内投资机构合作设立的首个投资平台,涵盖风能、太阳能、储能等新能源基础设施。 预计总

    06-18

  • 人工智能公司南栖仙策获数千万元Pre-A轮融资

    人工智能公司南栖仙策获数千万元Pre-A轮融资

    据3月10日消息,南栖仙策宣布获得数千万元Pre-A轮融资。 本轮领投方为高瓴创投。 基金包括高瓴创投、银杏谷资本、老股东永华投资、进化游戏等。 本轮融资将重点用于南栖仙策智能决策产品的研发和升级,完善行业客户销售和服务体系建设。 南栖仙策是南京大学人工智能创新研究

    06-17

  • 57岁李宁悄悄创办PE

    57岁李宁悄悄创办PE

    李宁拯救了英国百年老店。 本周,英国知名鞋履制造商Clarks的股东投票批准香港私募股权投资公司LionRock Capital收购Clarks。 这家英国百年企业避免了破产。 尽管交易对方莱恩资本并不出名,但其投资人李宁却是家喻户晓。 李宁2011年出生于广西壮族自治区柳州市,是20世纪最杰

    06-18

  • 星云互联网获超亿元B+轮融资,由中关村科学城科技成长基金、高通创投、扬子江资本联合投资

    星云互联网获超亿元B+轮融资,由中关村科学城科技成长基金、高通创投、扬子江资本联合投资

    投资圈(ID:pedaily)10月13日消息,北京星云车路协同解决方案提供商星云互联科技有限公司(以下简称“星云互联”)宣布获得超亿元B+轮融资。 本轮融资由中关村科学城科技成长基金、高通创投、长江资本联合投资。 星桥资本继续担任本轮独家投资方。 这是该公司继今年3月完成

    06-18

  • 苹果完成自研A16处理器设计并接受台积电涨价覆盖12万-15万片4nm产能

    苹果完成自研A16处理器设计并接受台积电涨价覆盖12万-15万片4nm产能

    据供应链行业人士透露,苹果自研新一代A16应用处理器已完成设计和定稿,将采用台积电4nm N4P工艺投产,预计下半年在台积电Fab18进入量产。 据悉,苹果的A16应用处理器将安装在新一代iPhone 14和iPad产品中。 由于晶圆代工产能供不应求,苹果为了保证产能,接受了涨价,并承包

    06-08

  • EUV光刻胶市场规模预计2025年突破2亿美元

    EUV光刻胶市场规模预计2025年突破2亿美元

    中国电子报电子材料咨询机构TECHCET最新研究报告(以下简称研究报告)显示,随着EUV在先进技术的加速引入高端芯片所需的制造工艺,金属氧化物、干沉积、多触发等EUV光刻胶的市场规模今年将超过2亿美元。 光刻胶是光刻工艺中的核心耗材,EUV光刻胶是增长最快的类别之一。 TECH

    06-06