Flutter的HTTP请求

It’s hard to do any sort of development without having to make some form of HTTP request, therefore, we’ll be looking at how to use the http plugin within Flutter.

无需进行某种形式的HTTP请求就很难进行任何类型的开发,因此,我们将研究如何在Flutter中使用http插件。

创建一个新的Flutter项目 (Creating a New Flutter Project)

In order to follow along with the setup we’ll be creating an example Flutter app. Assuming you already have the Flutter and Dart SDKs installed, run the following in your terminal:

为了进行设置,我们将创建一个Flutter应用示例。 假设您已经安装了Flutter和Dart SDK,请在终端中运行以下命令:

# New Flutter application
$ flutter create flutter_http

# Open this up inside of VS Code
$ cd flutter_http && code .

添加HTTP插件 (Adding the HTTP plugin)

Head over to your pubspec.yaml and add the following plugin:

转到您的pubspec.yaml并添加以下插件:

dependencies:
  flutter:
    sdk: flutter

  http: ^0.12.0+2

This is an official Flutter plugin published by dart.dev and it has 100 health score, therefore, we can trust the reliability of this plugin.

这是由dart.dev发布的官方Flutter插件,它的运行状况得分为100 ,因此,我们可以信赖该插件的可靠性。

HTTP请求 (HTTP Requests)

Our first task will be to create a class which we can use to interact with our API. We’ll create a new class named HttpService at lib/http_service.dart and add a getPosts function:

我们的第一个任务是创建一个可用于与API交互的类。 我们将在lib/http_service.dart创建一个名为HttpService的新类,并添加一个getPosts函数:

class HttpService {
  final String postsURL = "https://jsonplaceholder.typicode.com/posts";

  Future<List<Post>> getPosts() async {
    Response res = await get(postsURL);

    if (res.statusCode == 200) {
      List<dynamic> body = jsonDecode(res.body);

      List<Post> posts = body
          .map(
            (dynamic item) => Post.fromJson(item),
          )
          .toList();

      return posts;
    } else {
      throw "Can't get posts.";
    }
  }
}

As seen from the getPosts function, we’re firstly calling get from the http package on the postsURL.

getPosts函数可以看出,我们首先从postsURL上的http包调用get

Next, if that request was successful, we’re parsing the response and returning a List<Post> using Post.fromJson. Let’s go ahead and create the Post class at lib/posts_model.dart:

接下来,如果请求成功,我们将解析响应并使用Post.fromJson返回List<Post> 。 让我们继续在lib/posts_model.dart创建Post类:

import 'package:flutter/foundation.dart';

class Post {
  final int userId;
  final int id;
  final String title;
  final String body;

  Post({
    @required this.userId,
    @required this.id,
    @required this.title,
    @required this.body,
  });

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      userId: json['userId'] as int,
      id: json['id'] as int,
      title: json['title'] as String,
      body: json['body'] as String,
    );
  }
}

In order to serialize the response, we’re returning a new Post with the fromJson method based on a JSON Map. In a production application, I’d recommend using something like json_serializable to handle the serialization automatically.

为了序列化响应,我们将基于JSON Map使用fromJson方法返回一个新的Post 。 在生产应用程序中,建议使用json_serializable之类的东西来自动处理序列化。

显示帖子 (Displaying Posts)

With this in mind, let’s create a new page named PostsPage at lib/posts.dart:

考虑到这一点,让我们在lib/posts.dart创建一个名为PostsPage的新页面:

import 'package:flut_http/http_service.dart';
import 'package:flut_http/post_detail.dart';
import 'package:flut_http/post_model.dart';
import 'package:flutter/material.dart';

class PostsPage extends StatelessWidget {
  final HttpService httpService = HttpService();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Posts"),
      ),
      body: FutureBuilder(
        future: httpService.getPosts(),
        builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot) {
          if (snapshot.hasData) {
            List<Post> posts = snapshot.data;
            return ListView(
              children: posts
                  .map(
                    (Post post) => ListTile(
                      title: Text(post.title),
                      subtitle: Text("${post.userId}"),
                      onTap: () => Navigator.of(context).push(
                        MaterialPageRoute(
                          builder: (context) => PostDetail(
                            post: post,
                          ),
                        ),
                      ),
                    ),
                  )
                  .toList(),
            );
          } else {
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}

We’re using a FutureBuilder widget to interact with the getPosts() function. This allows us to determine when the List<Post> is ready and act accordingly.

我们正在使用FutureBuilder小部件与getPosts()函数进行交互。 这使我们能够确定List<Post> 何时准备就绪并采取相应措施。

If the snapshot.hasData is false, then we’re displaying the CircularProgressIndicator, otherwise we’re displaying the ListTile with various post information.

如果snapshot.hasData为false,则显示的是CircularProgressIndicator , 否则显示的ListTile带有各种发布信息的ListTile

Let’s make sure we update main.dart with the home of PostsPage:

确保我们使用main.darthome更新PostsPage

import 'package:flut_http/posts.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'HTTP',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.deepPurple,
      ),
      home: PostsPage(),
    );
  }
}

帖子详细 (Post Detail)

If the user taps on the post, we’re looking to navigate the user away to a PostDetail page. Let’s build that:

如果用户点击该帖子,那么我们希望将其导航到PostDetail页面。 让我们来构建:

import 'package:flut_http/post_model.dart';
import 'package:flutter/material.dart';

class PostDetail extends StatelessWidget {
  final Post post;

  PostDetail({@required this.post});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(post.title),
        ),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(12.0),
            child: Column(
              children: <Widget>[
                Card(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      ListTile(
                        title: Text("Title"),
                        subtitle: Text(post.title),
                      ),
                      ListTile(
                        title: Text("ID"),
                        subtitle: Text("${post.id}"),
                      ),
                      ListTile(
                        title: Text("Body"),
                        subtitle: Text(post.body),
                      ),
                      ListTile(
                        title: Text("User ID"),
                        subtitle: Text("${post.userId}"),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ));
  }
}

While this page doesn’t have any HTTP data, I’ve elected to add this to display the complete Post data.

虽然此页面没有任何HTTP数据,但我选择添加此数据以显示完整的Post数据。

删除 (DELETE)

Another example of such HTTP request is the use of the delete method. For example, inside of our HttpService we can create a deletePost(int id) method:

这种HTTP请求的另一个示例是delete方法的使用。 例如,在我们的HttpService内部,我们可以创建一个deletePost(int id)方法:

Future<void> deletePost(int id) async {
  Response res = await delete("$postsURL/$id");

  if (res.statusCode == 200) {
    print("DELETED");
  } else {
    throw "Can't delete post.";
  }
}

We can add an IconButton to the actions array within the AppBar so that whenever this is tapped a Post is deleted:

我们可以在AppBaractions数组中添加一个IconButton ,以便每当点击它时,就会删除一个Post

final HttpService httpService = HttpService();

@override
Widget build(BuildContext context) {
  return Scaffold(
      appBar: AppBar(
        title: Text(post.title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.delete),
            onPressed: () async {
              await httpService.deletePost(post.id);
              Navigator.of(context).pop();
            },
          )
        ],
      ),
    //
  )
}

结语 (Wrapping Up)

In this article, we looked at how to interact with the Flutter http package. This allowed us to get a list of posts, as well as delete an individual post.

在本文中,我们研究了如何与Flutter http包进行交互。 这使我们能够获取帖子列表,以及删除单个帖子。

Similar operations such as post, put, patch and so on are also available. Check out the documentation for more information on this.

也可以使用类似的操作,如postputpatch等。 请查阅文档以获取更多信息。

翻译自: https://www.digitalocean.com/community/tutorials/flutter-flutter-http

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值