iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 18
1
Mobile Development

iOS Developer Learning Flutter系列 第 18

iOS Developer Learning Flutter. Lesson17 API GET

Today Preview

定義Model > 打API > 顯示在畫面上
非常簡單、天天在做
我們來看看在Flutter上怎麼實現

1. 定義Model

關於Model問題
我一律建議使用quicktype神器
應該很難找到它不支援的語言

而且根據不同語言有很多客製化參數

複製貼上、打完收工

import 'dart:convert';

Users reqResFromJson(String str) => Users.fromJson(json.decode(str));
String reqResToJson(Users data) => json.encode(data.toJson());

class Users {
  Users({
    this.page,
    this.perPage,
    this.total,
    this.totalPages,
    this.userList,
  });

  int page;
  int perPage;
  int total;
  int totalPages;
  List<User> userList;

  factory Users.fromJson(Map<String, dynamic> json) => Users(
    page: json["page"],
    perPage: json["per_page"],
    total: json["total"],
    totalPages: json["total_pages"],
    userList: List<User>.from(json["data"].map((x) => User.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "page": page,
    "per_page": perPage,
    "total": total,
    "total_pages": totalPages,
    "data": List<dynamic>.from(userList.map((x) => x.toJson())),
  };
}

class User {
  User({
    this.id,
    this.email,
    this.firstName,
    this.lastName,
    this.avatar,
  });

  int id;
  String email;
  String firstName;
  String lastName;
  String avatar;

  factory User.fromJson(Map<String, dynamic> json) => User(
    id: json["id"],
    email: json["email"],
    firstName: json["first_name"],
    lastName: json["last_name"],
    avatar: json["avatar"],
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "email": email,
    "first_name": firstName,
    "last_name": lastName,
    "avatar": avatar,
  };
}

2. 打API

Flutter有提供HttpClient來跟網路溝通
網路IO會使用到async/await機制

  void getUsers(UsersCallback success) async {
    var urlString = "$domain/users?per_page=100";

    try {
    final httpClient = HttpClient();
      var request = await httpClient.getUrl(Uri.parse(urlString));
      var response = await request.close();
      if (response.statusCode == HttpStatus.ok) {

        var jsonString = await response.transform(utf8.decoder).join();
        var jsonMap = jsonDecode(jsonString);
        var users = Users.fromJson(jsonMap);
        success(users);
        
        httpClient.close();

      } else {
        print("Http NG");
      }

    } catch (exp) {
      print("Http Fail is $exp");
    }
  }

3. 顯示在畫面上

  1. 因應畫面有變動需求
    我們本頁使用StatefulWidget
  2. 先定義好hud跟list元件
  3. 沒資料時顯示hud, 否則顯示list
  4. initState時打API
  5. API回來時setState重繪畫面
class LessonPageApiGet extends StatefulWidget {
  @override
  _LessonPageApiGetState createState() => _LessonPageApiGetState();
}

class _LessonPageApiGetState extends State<LessonPageApiGet> {

  Users currentUsers;

  @override
  void initState() {
    super.initState();
    APIManager().getUsers((users) {
      setState(() {
        currentUsers = users;
      });
    });
  }

  @override
  Widget build(BuildContext context) {

    var hud = Container(
      alignment: Alignment.center,
      child: CircularProgressIndicator(),
    );

    var list = ListView.builder(
        itemExtent: 80,
        itemCount: (currentUsers == null) ? 0 : currentUsers.userList.length,
        itemBuilder: (ctx, idx) {

          var user = currentUsers.userList[idx];

          return Card(
              child: ListTile(
                leading: Container(
                  constraints: BoxConstraints(minWidth: 60, minHeight: 60),
                  color: Colors.black38,
                  child: Image.network(user.avatar, fit: BoxFit.fill),
                ),
                title: Text("${user.firstName} ${user.lastName}"),
                subtitle: Text(user.email),
              )
          );
        }
    );

    return Scaffold(
        appBar: AppBar(
          title: Text("第十五堂課"),
        ),
        body: (currentUsers == null) ? hud : list
    );
  }
}

本集內容Android版請見:iOS Developer Learning Android. Lesson 19

下集預告:API POST


上一篇
iOS Developer Learning Flutter. Lesson16 底部導航與頁籤
下一篇
iOS Developer Learning Flutter. Lesson18 API POST
系列文
iOS Developer Learning Flutter30

尚未有邦友留言

立即登入留言