Thứ bảy, 09/11/2019 | 00:00 GMT+7

Yêu cầu HTTP với Flutter


Thật khó để thực hiện bất kỳ loại phát triển nào mà không phải thực hiện một số hình thức yêu cầu HTTP, do đó, ta sẽ xem xét cách sử dụng plugin http trong Flutter.

Tạo một dự án Flutter mới

Để theo dõi quá trình cài đặt , ta sẽ tạo một ứng dụng Flutter mẫu. Giả sử bạn đã cài đặt Flutter và Dart SDK, hãy chạy phần sau trong terminal của bạn:

# New Flutter application $ flutter create flutter_http  # Open this up inside of VS Code $ cd flutter_http && code . 

Thêm plugin HTTP

Đi tới pubspec.yaml của bạn và thêm plugin sau:

dependencies:   flutter:     sdk: flutter    http: ^0.12.0+2 

Đây là một plugin Flutter chính thức được xuất bản bởi dart.dev và nó có 100 điểm sức khỏe , do đó, ta có thể tin tưởng vào độ tin cậy của plugin này.

Yêu cầu HTTP

Nhiệm vụ đầu tiên của ta sẽ là tạo một lớp mà ta có thể sử dụng để tương tác với API của bạn . Ta sẽ tạo một lớp mới có tên HttpService tại lib/http_service.dart và thêm một hàm 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.";     }   } } 

Như đã thấy từ hàm getPosts , trước tiên ta đang gọi get từ gói http trên postsURL .

Tiếp theo, nếu yêu cầu đó thành công, ta sẽ phân tích cú pháp phản hồi và trả về một List<Post> bằng Post.fromJson . Hãy tiếp tục và tạo lớp Post tại lib/posts_model.dart :

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,     );   } } 

Để tuần tự hóa phản hồi, ta sẽ trả lại một Post mới với phương thức fromJson dựa trên Map JSON. Trong một ứng dụng production , tôi khuyên bạn nên sử dụng thứ gì đó như json_serializable để xử lý việc tuần tự hóa tự động.

Hiển thị bài đăng

Với ý nghĩ này, hãy tạo một trang mới có tên là PostsPage tại lib/posts.dart :

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());           }         },       ),     );   } } 

Ta đang sử dụng một FutureBuilder widget để tương tác với getPosts() chức năng. Điều này cho phép ta xác định khi nào List<Post> đã sẵn sàng và hành động theo đó.

Nếu snapshot.hasData là false, thì ta đang hiển thị CircularProgressIndicator , nếu không , ta đang hiển thị ListTile với nhiều thông tin bài đăng khác nhau.

Hãy đảm bảo ta cập nhật main.dart với trang home của 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(),     );   } } 

Ảnh chụp màn hình Danh sách bài đăng

Đăng chi tiết

Nếu user nhấn vào bài đăng, ta đang tìm cách chuyển user đến trang PostDetail . Hãy xây dựng điều đó:

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}"),                       ),                     ],                   ),                 ),               ],             ),           ),         ));   } } 

Mặc dù trang này không có bất kỳ dữ liệu HTTP nào, nhưng tôi đã chọn thêm dữ liệu này để hiển thị dữ liệu Bài đăng hoàn chỉnh.

Ảnh chụp màn hình chi tiết bài đăng

XÓA BỎ

Một ví dụ khác về yêu cầu HTTP như vậy là sử dụng phương thức delete . Ví dụ, bên trong HttpService ta , ta có thể tạo một phương thức 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.";   } } 

Ta có thể thêm một IconButton vào mảng actions trong AppBar để khi nào AppBar vào AppBar này, một Post sẽ bị xóa:

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();             },           )         ],       ),     //   ) } 

Kết thúc

Trong bài viết này, ta đã xem xét cách tương tác với gói Flutter http . Điều này cho phép ta có được danh sách các bài đăng, cũng như xóa từng bài đăng.

Các thao tác tương tự như post , put , patch , v.v. cũng có sẵn. Kiểm tra tài liệu để biết thêm thông tin về điều này.


Tags:

Các tin liên quan