「这是我参加11月更文挑战的第12天,活动详情查看:2021最终一次更文挑战」

Hi

  • Wechat: RyukieW
  • 微信公众号:LabLawliet
  • 技术文章归档
  • Github
我的个人项目 扫雷Elic 无尽天梯 梦见账本 隐私拜访记载
类型 游戏 财务 东西
AppStore Elic Umemi 隐私拜访记载

更多专栏:

Lawliet的独立开发碎碎念

Lawliet的iOS游园会

Lawliet的iOS底层实验室

Lawliet的iOS逆向实验室

Lawliet的刷题小本本

Lawliet的Flutter实验室

Flutter小技巧|从侧索引条封装看手势处理与clamp函数

Flutter小技巧|Widget初始化办法重写&链式调用&排序

Flutter小技巧|经过多样式Cell看断语

Flutter小技巧|ListView滑动到分组头部

前语

在 iOS 开发中 咱们经常运用 CocoaPods 等东西进行包办理。那么在 flutter 开发中又该怎么进行呢?

这儿以会话列表为例结合导入网络库:http进行解读。

一、 导入依靠库

这是官方供给来一个网络库:http

点击仿制

Flutter小技巧|第三方库导入与网络数据展示(三种形式)

1.1 修正 pubspec.yaml 配置文件

将仿制的信息补充进配置文件

Flutter小技巧|第三方库导入与网络数据展示(三种形式)

1.2 更新依靠库

Flutter小技巧|第三方库导入与网络数据展示(三种形式)

1.3 在运用的当地导入

import 'package:http/http.dart' as http;

二、 异步函数

2.1 简略汇总Service

简略汇总一下Service,便于后续运用。

import 'package:flutter/material.dart';
class ServiceURL {
  /// 会话列表
  static Uri conversationList = Uri.parse('xxxxxx');
}

2.2 发送恳求

这儿简略选择在 initState 中进行网络恳求,调用移步办法

  @override
  void initState() {
    super.initState();
    _loadConversation();
  }
  /// 加载会话列表
  void _loadConversation() async {
    var response = await http.get(ServiceURL.conversationList);
    print(response.body);
  }

这儿可以发现,和咱们在 iOS 开发中的网络恳求的调用形式有很大不同。iOS开发中咱们都是经过回调的形式接纳恳求结果的。这儿运用 await

三、 数据模型转换

接纳到网络数据后咱们天然需求进行数据模型的转换。

3.1 界说数据模型

import 'package:flutter/material.dart';
class ConversationData {
  final String nick;
  final String avatar;
  final String lastestMessage;
  ConversationData({
    required this.nick,
    required this.avatar,
    required this.lastestMessage,
  });
  factory ConversationData.formMap(Map map) {
    return ConversationData(
      nick: map['nick'],
      avatar: map['avatar'],
      lastestMessage: map['lastest_message'],
    );
  }
}

3.2 Json 转 Map

  List _conversations = [];
  /// 加载会话列表
  void _loadConversation() async {
    var response = await http.get(ServiceURL.conversationList);
    if (response.statusCode == 200) {
      final bodyMap = json.decode(response.body);
      _conversations = bodyMap['lists']
                            .map((item) {
                                return ConversationData.formMap(item);
                            })
                            .toList();
    } else {
      throw Exception('恳求失利:${response.statusCode}');
    }
  }

3.3 构建 Cell

  • Text
    • 样式设置
    • 缩略方法设置
    • 设置最大宽度
  • Container
    • 设置图片圆角
class ConversationCell extends StatelessWidget {
  ConversationCell({required this.conversation});
  final ConversationData conversation;
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 60,
      color: Colors.white,
      child: Stack(
        children: [
          Align(
            alignment: Alignment.center,
            child: Container(
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  const SizedBox(
                    width: 12,
                  ),
                  // 圆角
                  Container(
                    width: 48,
                    height: 48,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(4),
                      image: DecorationImage(
                          // 网络图片
                        image: NetworkImage(conversation.avatar),
                      ),
                    ),
                  ),
                  const SizedBox(
                    width: 12,
                  ),
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const SizedBox(height: 12),
                      Text(
                        conversation.nick,
                        maxLines: 1,
                        style: const TextStyle(
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                      ),
                      Container(
                          // 限制宽度
                        width: UIConfig.screenWidth(context) * 0.7,
                        child: Text(
                          conversation.lastestMessage,
                          maxLines: 1,
                          // 缩略样式
                          overflow: TextOverflow.ellipsis,
                          style: const TextStyle(
                            fontSize: 12,
                            fontWeight: FontWeight.w400,
                          ),
                        ),
                      )
                    ],
                  ),
                ],
              ),
            ),
          ),
          // 分割线
          Align(
            alignment: Alignment.bottomCenter,
            child: Container(
              margin: const EdgeInsets.only(left: 70),
              height: 0.5,
              color: Colors.grey,
            ),
          ),
        ],
      ),
    );
  }
}

3.4 构建 ListView

Widget _itemForRow(BuildContext context, int index) {
    return ConversationCell(conversation: _conversations[index]);
}
body: Container(
        color: Colors.yellow,
        child: ListView.builder(
          itemBuilder: _itemForRow,
          itemCount: _conversations.length,
        ),
      ),

3.5 效果

Flutter小技巧|第三方库导入与网络数据展示(三种形式)

四、 Future & FutureBuilder

4.1 恳求办法修正

之前的加载办法:

  /// 加载会话列表
  void _loadConversation() async {
    var response = await http.get(ServiceURL.conversationList);
    if (response.statusCode == 200) {
      final bodyMap = json.decode(response.body);
      _conversations = bodyMap['lists']
                            .map((item) {
                                return ConversationData.formMap(item);
                            })
                            .toList();
    } else {
      throw Exception('恳求失利:${response.statusCode}');
    }
  }

修正为:

  /// 加载会话列表
  Future<List> _loadConversation() async {
    var response = await http.get(ServiceURL.conversationList);
    if (response.statusCode == 200) {
      final bodyMap = json.decode(response.body);
      return bodyMap['lists'].map((item) {
        return ConversationData.formMap(item);
      }).toList();
    } else {
      throw Exception('恳求失利:${response.statusCode}');
    }
  }

4.2 ListView 修正

AsyncSnapshot

包含有绑定的 future 回调的数据,也包含异步任务的状况。咱们可以用来判别是否展示加载页面。

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(...),
      body: Container(
        color: Colors.yellow,
        child: FutureBuilder(
          // 传入 Future
          future: _loadConversation(),
          builder: (context, AsyncSnapshot snap){
            // 判别恳求状况
            if (snap.connectionState != ConnectionState.done) {
              return const Center(
                child: Text('Loading'),
              );
            }
            // 根据结果处理数据展示
            return ListView(
              children: snap.data.map<Widget>((item){
                return ConversationCell(conversation: item);
              }).toList(),
            );
          },
        ),
      ),
    );
  }

4.3 看看效果

Flutter小技巧|第三方库导入与网络数据展示(三种形式)

五、 结合上面两种方法

结合上面两种方法,这儿运用 Future 调整加载数据的函数。

5.1 恳求函数修正

  /// 加载会话列表
  Future<List> _loadConversation() async {
    _isLoading = true;
    var response = await http.get(ServiceURL.conversationList);
    _isLoading = false;
    if (response.statusCode == 200) {
      final bodyMap = json.decode(response.body);
      final result = bodyMap['lists'].map((item) {
        return ConversationData.formMap(item);
      }).toList();
      return result;
    } else {
      throw Exception('恳求失利:${response.statusCode}');
    }
  }

5.2 回调处理

  @override
  void initState() {
    super.initState();
    _loadConversation().then((value) {
      // value 就是 Future 里 return 的结果
      setState(() {
        _conversations = value;
      });
    });
  }

5.3 反常处理

经过 Future 咱们也可以捕捉反常。

  @override
  void initState() {
    super.initState();
    _loadConversation().then((value) {
      setState(() {
        _conversations = value;
      });
    }).catchError((error) {
      print(error);
    });
  }

六、 总结

  • 第一种方法愈加接近咱们 iOS 开发中的思路
  • 第二种方法 Future & FutureBuilder 愈加充分利用 Future 特性
  • 而结合二者的方法则对我这个iOS刚入门Flutter的新手而言,愈加了解一起也有一些新的体验

完好代码

GitHub