快途物流完成1亿元B轮融资,中为资本、碧桂园创投等参与,
06-18
我已经使用 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
在_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.组件的文档 当一个组件开发完成后,我们应该为该组件编写文档,以便其他开发人员能够快速了解??该组件的用法和功能。没有文档,没有人敢使用组件。
现在的开发者太懒了,不愿意花太多的时间和精力去学习如何使用组件。在编写组件文档时,我们应该遵循以下原则:? 简洁明了:文档应该简洁明了,不应该包含太多废话和无用的信息。
? 示例代码:文档应包含示例代码,以便开发人员能够快速了解??组件的用法。 ? 参数说明:文档中应包含参数说明,以便开发人员了解组件的参数和功能。
? 返回值描述:文档应包含返回值描述,以便开发人员能够了解组件的返回值和功能。 ? 效果演示:文档中应包含效果演示,以便开发人员了解组件的效果和功能。
今天就讲到这里,希望对大家有帮助。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-18
06-17
06-18
06-18
06-17
06-18
06-06
最新文章
【玩转GPU】ControlNet初学者生存指南
【实战】获取小程序中用户的城市信息(附源码)
包雪雪简单介绍Vue.js:开学
Go进阶:使用Gin框架简单实现服务端渲染
线程池介绍及实际案例分享
JMeter 注释 18 - JMeter 常用配置组件介绍
基于Sentry的大数据权限解决方案
【云+社区年度征文集】GPE监控介绍及使用