博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flutter 构建完整应用手册-联网
阅读量:6082 次
发布时间:2019-06-20

本文共 7863 字,大约阅读时间需要 26 分钟。

hot3.png

从互联网上获取数据

从大多数应用程序获取互联网上的数据是必要的。 幸运的是,Dart和Flutter为这类工作提供了工具!

路线

  1. 使用http包发出网络请求
  2. 将响应转换为自定义Dart对象
  3. 用Flutter获取并显示数据

1.使用http包发出网络请求

包提供了从互联网获取数据的最简单方法。

在这个例子中,我们将使用方法从获取示例文章。

Future
fetchPost() { return http.get('https://jsonplaceholder.typicode.com/posts/1');}

http.get方法返回一个包含Response的Future。

  • 是与异步操作一起工作的核心Dart类。 它用于表示未来某个时间可能会出现的潜在价值或错误。
  • http.Response类包含从成功的http调用收到的数据。

2.将响应转换为自定义Dart对象

虽然提出网络请求很容易,但使用原始Future<http.Response>并不方便。 为了让我们的生活更轻松,我们可以将http.Response转换为我们自己的Dart对象。

创建一个Post类

首先,我们需要创建一个Post类,其中包含来自我们网络请求的数据。 它还将包含一个工厂构造函数,允许我们从json创建一个Post。

手动转换JSON只是一种选择。 有关更多信息,请参阅关于的完整文章。

class Post {  final int userId;  final int id;  final String title;  final String body;  Post({this.userId, this.id, this.title, this.body});  factory Post.fromJson(Map
json) { return new Post( userId: json['userId'], id: json['id'], title: json['title'], body: json['body'], ); }}

将http.Response转换为Post

现在,我们将更新fetchPost函数以返回Future<Post>。 为此,我们需要:

  • 使用dart:convert包将响应正文转换为json Map
  • 使用fromJson工厂函数将json Map转换为Post。
Future
fetchPost() async { final response = await http.get('https://jsonplaceholder.typicode.com/posts/1'); final responseJson = json.decode(response.body); return new Post.fromJson(responseJson); }

万岁! 现在我们有一个功能,我们可以调用从互联网上获取Post!

3.用Flutter获取并显示数据

为了获取数据并将其显示在屏幕上,我们可以使用小部件! Flutter附带FutureBuilder部件,可以轻松处理异步数据源。

我们必须提供两个参数:

使用的Future。 在我们的例子中,我们将调用我们的fetchPost()函数。
一个builder函数,告诉Flutter渲染什么,取决于Future的状态:加载,成功或错误。

new FutureBuilder
( future: fetchPost(), builder: (context, snapshot) { if (snapshot.hasData) { return new Text(snapshot.data.title); } else if (snapshot.hasError) { return new Text("${snapshot.error}"); } // By default, show a loading spinner return new CircularProgressIndicator(); },);

完整例子

import 'dart:async';import 'dart:convert';import 'package:flutter/material.dart';import 'package:http/http.dart' as http;Future
fetchPost() async { final response = await http.get('https://jsonplaceholder.typicode.com/posts/1'); final responseJson = json.decode(response.body); return new Post.fromJson(responseJson);}class Post { final int userId; final int id; final String title; final String body; Post({this.userId, this.id, this.title, this.body}); factory Post.fromJson(Map
json) { return new Post( userId: json['userId'], id: json['id'], title: json['title'], body: json['body'], ); }}void main() => runApp(new MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Fetch Data Example', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new Scaffold( appBar: new AppBar( title: new Text('Fetch Data Example'), ), body: new Center( child: new FutureBuilder
( future: fetchPost(), builder: (context, snapshot) { if (snapshot.hasData) { return new Text(snapshot.data.title); } else if (snapshot.hasError) { return new Text("${snapshot.error}"); } // By default, show a loading spinner return new CircularProgressIndicator(); }, ), ), ), ); }}

进行认证请求

为了从许多Web服务获取数据,您需要提供授权。 有很多方法可以做到这一点,但也许最常见的方法是使用Authorization HTTP标头。

添加授权头部信息

包提供了一种方便的方法来为请求添加请求头。 您还可以利用dart:io软件包来处理常见的HttpHeaders。

Future
fetchPost() { return http.get( 'https://jsonplaceholder.typicode.com/posts/1', // Send authorization headers to your backend headers: {HttpHeaders.AUTHORIZATION: "Basic your_api_token_here"}, );}

完整例子

这个例子建立在的配方上。

import 'dart:async';import 'dart:convert';import 'dart:io';import 'package:http/http.dart' as http;Future
fetchPost() async { final response = await http.get( 'https://jsonplaceholder.typicode.com/posts/1', headers: {HttpHeaders.AUTHORIZATION: "Basic your_api_token_here"}, ); final json = json.decode(response.body); return new Post.fromJson(json); }class Post { final int userId; final int id; final String title; final String body; Post({this.userId, this.id, this.title, this.body}); factory Post.fromJson(Map
json) { return new Post( userId: json['userId'], id: json['id'], title: json['title'], body: json['body'], ); }}

使用WebSockets

除了正常的HTTP请求外,我们还可以使用WebSockets连接到服务器。 WebSocket允许与服务器进行双向通信而无需轮询。

在这个例子中,我们将连接到由。 服务器将简单地发回我们发送给它的相同消息!

路线

  • 连接到WebSocket服务器
  • 监听来自服务器的消息
  • 将数据发送到服务器
  • 关闭WebSocket连接

1.连接到WebSocket服务器

包提供了我们需要连接到WebSocket服务器的工具。

该软件包提供了一个WebSocketChannel,它允许我们既监听来自服务器的消息,又将消息推送到服务器。

在Flutter中,我们可以创建一个连接到服务器的WebSocketChannel:

final channel = new IOWebSocketChannel.connect('ws://echo.websocket.org');

2.监听来自服务器的消息

现在我们建立了连接,我们可以收听来自服务器的消息。

在我们发送消息给测试服务器之后,它会发回相同的消息。

我们如何听取消息并显示它们? 在这个例子中,我们将使用部件来侦听新消息和一个部件来显示它们。

new StreamBuilder(  stream: widget.channel.stream,  builder: (context, snapshot) {    return new Text(snapshot.hasData ? '${snapshot.data}' : '');  },);

这个怎么用?

WebSocketChannel从服务器提供消息 。

Stream类是dart:async包的基础部分。 它提供了一种方法来侦听来自数据源的异步事件。 与将返回单个异步响应的Future不同,Stream类可以随着时间的推移传递许多事件。

部件将连接到Stream,并在每次接收到事件时使用给定的builder函数请求Flutter重建!

3.将数据发送到服务器

为了将数据发送到服务器,我们将消息add到由WebSocketChannel提供的sink接收器。

channel.sink.add('Hello!');

这个怎么用

WebSocketChannel提供了一个来将消息推送到服务器。
StreamSink类提供了将同步或异步事件添加到数据源的一般方法。

4.关闭WebSocket连接

在我们完成使用WebSocket之后,我们将要关闭连接! 为此,我们可以关闭sink。

channel.sink.close();

完整例子

import 'package:flutter/foundation.dart';import 'package:web_socket_channel/io.dart';import 'package:flutter/material.dart';import 'package:web_socket_channel/web_socket_channel.dart';void main() => runApp(new MyApp());class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    final title = 'WebSocket Demo';    return new MaterialApp(      title: title,      home: new MyHomePage(        title: title,        channel: new IOWebSocketChannel.connect('ws://echo.websocket.org'),      ),    );  }}class MyHomePage extends StatefulWidget {  final String title;  final WebSocketChannel channel;  MyHomePage({Key key, @required this.title, @required this.channel})      : super(key: key);  @override  _MyHomePageState createState() => new _MyHomePageState();}class _MyHomePageState extends State
{ TextEditingController _controller = new TextEditingController(); @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text(widget.title), ), body: new Padding( padding: const EdgeInsets.all(20.0), child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children:
[ new Form( child: new TextFormField( controller: _controller, decoration: new InputDecoration(labelText: 'Send a message'), ), ), new StreamBuilder( stream: widget.channel.stream, builder: (context, snapshot) { return new Padding( padding: const EdgeInsets.symmetric(vertical: 24.0), child: new Text(snapshot.hasData ? '${snapshot.data}' : ''), ); }, ) ], ), ), floatingActionButton: new FloatingActionButton( onPressed: _sendMessage, tooltip: 'Send message', child: new Icon(Icons.send), ), // This trailing comma makes auto-formatting nicer for build methods. ); } void _sendMessage() { if (_controller.text.isNotEmpty) { widget.channel.sink.add(_controller.text); } } @override void dispose() { widget.channel.sink.close(); super.dispose(); }}

转载于:https://my.oschina.net/u/3647851/blog/1791953

你可能感兴趣的文章
文件系统的几种类型:ext3, swap, RAID, LVM
查看>>
CRC与MD5的异同
查看>>
html 区域内查找,高亮,定位,类似于Ctrl+F
查看>>
代码三要素——赢得面试官芳心
查看>>
Springboot在Util类里面注入接口
查看>>
VI常用命令
查看>>
MySql 按时间段查询数据方法
查看>>
上传jar包到nexus私服
查看>>
idea工具java日志 Log4j+slf4j使用
查看>>
Solr6.6配置jetty访问日志
查看>>
Android ListView上下滑动弹性动画
查看>>
Android LruCache 二级缓存
查看>>
Java使用Redis
查看>>
【Cloud Foundry 应用开发大赛】“八卦街”后台管理系统
查看>>
ice版本resize 错误调试(Host key verification failed)
查看>>
http://fulinweiyang.iteye.com/
查看>>
php ssh2
查看>>
状态码
查看>>
Git合并多个 Commit
查看>>
结合Spring和Groovy解决脚本热加载
查看>>