在您的Flutter工具带上添加另一个槽口。

本文是我对Flutter / Dart的沉思和所学内容的延续,您可能希望看到我之前的文章“开始构建Flutter工具带”。 那篇文章中有关于RefreshIndicator小部件和Dart Future .then回调的引用,在本文中我只看过它们。 此外,撰写本文是为了帮助支持GDG Bronx Flutter研究果酱,因此该受众群体包含一些非常基本的Flutter / Dart技巧。

DartPad。

Dartpad是Dart编辑器的替代品,是测试或学习Dart语言或调整代码段的简便方法。 这是Dart在线编辑器。 这是一个屏幕截图。

左侧提供的代码是默认代码,您可以删除for循环并将代码放入其中。 在顶部和中间的右侧是“运行”按钮,它将执行您的代码。 屏幕右上方显示了执行代码的结果。 如果您的代码中有语法错误,它将显示在屏幕的右下方,如下所示。 for循环中i变量的增量已从i ++更改为i +++ ,这将显示为错误。

DartPad的局限性之一是它不支持发布管理器,因此它目前无法使用Dart包。

字符串插值。

字符串插值是一种轻松地将嵌入式文字与Dart变量的值组合在一起的方法。 这是一个字符串示例:

 字符串hello = “ Hello World” ; 
print( “ hello string = $ hello );

变量名之前的$告诉它在其位置包含变量值,从而易于将内联文字’hello string =’与hello String变量的值组合在一起。 它将打印如下:

 你好字符串=你好世界 

$选项仅适用于简单变量,因此要处理某种类型的数组或Dart表达式,请使用语法$ {} ,其中将复杂表达式放在括号之间。 这是一个示例,或使用DartPad中提供的默认代码从for循环打印。

  for (int i = 0; i <5; i ++){ 
print( 'hello $ {i + 1} ' );
}

$ {i + 1}i的迭代值,并将其加1 ,然后使用该结果。 这也可以应用于数组和列表,以及一系列内联文字,等等。

这是上面两个String Interpolation示例的DartPad示例。

Dart Language导览首先显示的基本程序中也包含简短的解释和示例。

调试打印。

有时候,您在开发或测试应用程序时希望有打印声明,但是您不想将其包含在已发布的应用程序版本中。 这就是debugPrint语句的来源。它与print相同,但是有两个例外。 第一个很明显,因为它仅在调试模式下而不在释放模式下打印。 第二点不太明显,因为debugPrint是Foundation库的一部分,所以需要使用导入才能使用它,这可能在您的代码中,但是如果没有,则必须使用包含Foundation库(例如Material或Cupertino)的导入,如下:

  导入'package:flutter / cupertino.dart' ; 
导入'package:flutter / material.dart' ;

热重装很棒,但是…

热重装在Flutter中非常出色,并且可以实现它所说的,但是在处理有状态小部件时,您应该意识到一件事。 热重载在您调试应用程序时会保持状态,因此,如果您尝试调试有状态窗口小部件的initState,则必须退出该屏幕(小部件),然后返回该屏幕以返回initState进程。

时间戳记。

这是获取Unix时间戳或“纪元”时间戳的快速参考,该时间戳是自1970年1月1日午夜以来的秒数,而ISO 8601是国际公认的表示日期和时间的方式。 Unix时间戳是数字的简写,而ISO 8601是长的,更易理解的日期时间戳。

Unix时间戳记— DateTime.now()。millisecondsSinceEpoch

ISO 8601时间戳记—在这里,我们首先创建一个ISO 8601字符串。

  DateTime myDatetime =日期时间。  解析“ 2018-10-26 17:01:01” ); 
打印(myDatetime.toIso8601String());

这将打印2018–10–26T17:01:01.000 ,并且不包含UTC信息。

本节中的示例仅是为了使您了解一些处理日期和时间的类,而不是处理使用它们进行编程的所有细微差别。 上面使用的第一个Dart类是DateTime,它是用于处理日期和时间的非常有用的类。 相关的Dart类Duration是一种引用时间实例的方法。 在下面有关HTTP超时的部分中引用了它。 这是表示计时器,动画持续时间以及日期和时间计算中使用的持续时间的一种非常简单的方法。 这是一个简单的持续时间:

 持续时间(秒:5) 

您可以在空闲时查看DateTime和Duration类。 最后一条有用的信息是如何格式化字符串并将其解析为DateTime格式,DateFormat页面非常有用。 DateFormat类是intl库的一部分,该类对于国际化很有用,此外它还支持日期时间局部性,因为它支持UTC。

这是一篇有关日期的文章。

将数据传递到另一个屏幕(小部件)。

在屏幕之间保留或共享数据有多种方法。 有两个选项使用全局变量,静态变量,SharedPreference,文件或数据库。 在这种情况下,为简单起见,我们将仅将String传递到下一个屏幕。 为此,我们将使用MaterialPageRoute通过其构造函数传递到接收屏幕小部件。 因此,首先我们将创建一个“路线”,并使用其生成器来调用接收屏幕小部件,如下所示:

  var route = new MaterialPageRoute( 
生成器:(BuildContext上下文)=>
新的 NextScreen(passedString: Your String ),
);

因此,使用创建的“路线”调用NextScreen的小部件,但该路线实际上并不能将您带到新的小部件或屏幕。 为此,使用导航器。 导航器是一个堆叠的对象,用于将您导航到的路由保留在其堆栈中。 因此,作为堆栈对象,您显然可以推入或弹出路由,因此有更多选择。 在这种情况下,我们将使用导航器按以下方式推送路线:

 航海家。  context ).push(route); 

现在将调用NextScreen小部件,但是如何获取小部件以接收值。 全部在小部件构造函数中。 因此,这是一个用于此目的的有状态小部件。

  导入'package:flutter / material.dart' ; 


NextScreen 扩展了 StatefulWidget {

最后的字符串passedString ;

NextScreen({Key key, this。passedString }): 超级 (key:key);

@override
_NextScreenState createState()=> _NextScreenState();
}

_NextScreenState 扩展了 State {
@override
小部件build(BuildContext context){
return Text( $ { 小部件 。passedString } );
}
}

构造函数中的this.passedString值passedString变量。 只有构造函数可以初始化它的最终变量,这是其目的的一部分。 注意Key参数和对super(key:key)的调用,这是因为所有小部件都可以具有全局键,并在必要时进行引用。 密钥是每个小部件的唯一标识符,类似于Android中的viewId。 “键”被传递给上级,在本例中为StatefulWidget。 因此,这里最后要提到的是“小部件”。 符号。 “小部件”。 符号是指StatefulWidget中定义的变量,有时也称为“外部状态”变量,因为它是在State类对象之外定义的。

用于分页数据加载和刷新的UI模式。

简单易用的UI模式。 由于无线电的使用是电池昂贵的命题,并且具有可能存在的大量数据列表,因此这常常导致分页的加载数据的方法。 之前我已经讨论过使用RefreshIndicator小部件在Flutter中实现对ListView或等效项执行拉动刷新操作的操作有多么容易。 RefreshIndicator窗口小部件很容易赢得用户,使用户可以随时更新潜在变化的数据,特别是对于核心用户功能。 这给我带来了另一种轻松实现UI模式的方法,不仅可以刷新数据,还可以实现如何加载更多先前已卸载的数据,尤其是在数据列表较长时。 显然,我建议您先对列表进行优先排序。

如果从顶部拉出,UI模式将允许您拉动刷新列表视图或网格视图数据,如果从底部拉出,则可以以分页样式加载更多数据。 在研究了RefreshIndicator之后,它只能从列表顶部进行拉动刷新。 RefreshIndicator的onRefresh回调方法仅响应从顶部拉出,而对从底部拉出不执行任何操作。 我考虑过创建一个自定义的RefreshIndicator,但认为这将是太多的工作,并且很难在以后提供支持。 经过进一步的研究并感谢“ Zroq”,一个更简单的选择是添加一个ScrollControl侦听器,并使它对自下而上的操作做出响应。

因此,让我们从包装ListView或GridView类型小部件的RefreshIndicator开始。

 刷新指标 
onRefresh:_yourMethodToRefreshYouData,

然后,您只需要在_yourMethodToRefreshYouData方法中定义如何刷新数据即可,这就是填充列表的开始方式。

  Future  _yourMethodToRefreshYouData() 异步 { 
等待 actualMethodToRefreshData; 返回null ;
}

现在,您已经轻松添加了RefreshIndicator,下一步是添加ScrollController,它是侦听器以响应自下而上的操作。

首先在您的state方法中添加一个ScrollController。

  var _scrollController = new ScrollController(); 

然后在initState中,添加Scroll Controller侦听器,如下所示:

  如果_scrollController。position。pixel == 
_scrollController职位maxScrollExtent ){
loadMoreContent();
}

最后自己清理一下,在小部件生命周期的处理部分中不需要滚动控制器时将其删除。

  @override 
无效 dispose(){
_scrollController .dispose();
}

这不是处理此问题的唯一方法,而是一种非常简单的方法。 有一些dart库也可以执行此操作,但是我不想依赖于它们的支持程度或支持程度。 此外,以上方法仅着眼于如何处理UI中的基础知识。 由于您可能有许多不同的来源,因此如何编码和管理实际的数据刷新,这里不再讨论。 此外,数据抽象也不会被覆盖,例如说您可以将数据抽象为三个模型,即listModel,pageModel和repositoryModel。

Http超时与ANR。

许多应用程序连接到Internet,并通过一些API端点从HTTP站点检索有关我们应用程序的信息。 太好了,我有我的数据,而且在旅途中,我的用户很高兴,除非您的设备上没有良好的一致互联网连接。 如果您自己不处理,HTTP库将向您的应用返回TimeoutException。 HTTP库对此有一个答案,即超时方法。 在您的http请求上,可以将呼叫添加到.timeout方法回调中,其持续时间如下:

  .timeout(const持续时间(秒:5),onTimeout:_onTimeout); 

然后,您可以定义方法_onTimeout,以在发生超时时以您认为必要的任何方式警告用户该问题。

我正在查看的一个问题是ANR(Android无响应),该问题限制为5秒,这会导致您的应用程序在无响应时停止。 我还没有使用Flutter应用程序对此进行测试,但是时间会证明一切。 因此,在上面,您可能希望使超时检查少于5秒,这对于持续时间确实很容易,如下所示:

  .timeout( const持续时间(秒:4,毫秒:750),onTimeout:_onTimeout); 

多部分或表单数据的HTTP POST字段。

通常,我们通常只是发出HTTP获取信息以从我们的端点中的一个获取信息。 在某些情况下,您需要将数据发布到端点。 有很多将文件发布到服务器的示例,因此在此不做介绍。 此示例适用于您只想将一些字段发布到服务器端点的情况,而我没有找到很多示例。 调用的格式略有不同,因此,为了方便起见,这是一条HTTP帖子,用于将数据发布到“ multipart / form-data ”的内容类型以帮助您入门。

  var uri = Uri。  解析“ https://www.yoursite.com/api/v1/youendpoint/” ); 
var request = new http.MultipartRequest( “ POST” ,uri);
请求。 标头 [ 'content-type' ] = “ multipart / form-data; charset = utf-8” ;
请求。 字段 [ 'yourfield' ] = ' $ yourfieldvalue ' ;

对于多部分帖子请求,使用Uri相对于简单URL更为具体。 标头和字段非常简单。 上面唯一要注意的是服务器可能支持不同的字符集,通常服务器是utf-16,而手机支持utf-8。 在上面的标头content-type参数中,它包含charset = utf-8 ,因为移动设备使用utf-8。

多部分或表单数据的HTTP PUTTING字段。

这是一个与上面的http帖子非常相似的http放置示例。 它也只是部分使用Uri,但此外,以下示例还显示了如何立即从Future中检索http响应。 它对Future使用.then回调,如下所示:

  var uri = Uri。  解析“ https://www.yourwebsite.com/api/v1/yourendpoint/” ); 
var request = new http.MultipartRequest( “ PUT” ,uri);
请求。 标头 [ 'content-type' ] = “ multipart / form-data; charset = utf-8” ;
请求。 字段 [ 'field1' ] = 字段 1;
请求。 字段 [ 'field2' ] = 字段2


等待 request.send(). then ((response){
if (response。statusCode == nnn){
//做点什么
}
});

Flutter Pub是一个中等规模的出版物,旨在为您带来有关该伟大技术的最新,令人惊叹的资源,例如文章,视频,代码,播客等,以教您如何使用它构建漂亮的应用程序。 您可以在Facebook,Twitter和Medium上找到我们,或者在此处了解有关我们的更多信息。 我们很想联系! 如果您是有兴趣为我们写作的作家,那么可以按照这些指南进行操作。