前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flutter】Future 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )

【Flutter】Future 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )

作者头像
韩曙亮
发布2023-03-29 15:47:27
1.7K0
发布2023-03-29 15:47:27
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

一、FutureBuilder 简介


FutureBuilder 本质是组件 : FutureBuilder 构造好以后 , 会自动执行异步操作 , 并返回 Widget 组件 , 因此 FutureBuilder 也是一个组件 , 在不同的状态下显示不同样式的组件 ;

FutureBuilder 泛型设置 : FutureBuilder 的泛型 , 表示异步调用得到的 Future 的泛型 , 也就是返回结果的格式 ; FutureBuilder<CommonModel> 表示异步调用 Future 的返回值是 Future<CommonModel> ;

Future<T> future 参数设置 : 这是设置的是异步操作方法 , 下面的 httpGet() 方法 , 是一个返回 Future<CommonModel> 类型的方法 , 可以直接设置给 FutureBuilder 构造函数作为参数 ;

代码语言:javascript
复制
  /// 调用 Http Get 方法 , 获取服务器的 json 数据
  Future<CommonModel> httpGet() async {
    //var url = Uri.parse('https://jsonplaceholder.typicode.com/posts/1');
    var url = Uri.parse('https://www.devio.org/io/flutter_app/json/test_common_model.json');
    // 异步请求 , 获取远程服务器信息
    final response = await http.get(url);

    /// 处理中文乱码
    Utf8Decoder utf8decoder = Utf8Decoder();
    /// 将二进制 Byte 数据以 UTF-8 格式编码 , 获取编码后的字符串
    String responseString = utf8decoder.convert(response.bodyBytes);

    // 将 json 字符串信息转为 Map<String, dynamic> 类型的键值对信息
    Map<String, dynamic> jsonMap = json.decode(responseString);
    return CommonModel.fromJson(jsonMap);
  }

@required AsyncWidgetBuilder<T> builder 参数是必须设置的参数 , 该参数是 AsyncWidgetBuilder<T> 类型 的方法 :

代码语言:javascript
复制
typedef AsyncWidgetBuilder<T> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot);

传入的参数如下 : 自己写一个匿名函数 , 参数是 BuildContext context, AsyncSnapshot<T> snapshot , 返回值是 Widget ;

代码语言:javascript
复制
(BuildContext context, AsyncSnapshot<CommonModel> snapshot){
	return Text("");
}

在上述 匿名函数 中 , 开始根据 AsyncSnapshot<CommonModel> snapshot 参数进行各种操作 , BuildContext context 参数在本次没有用到 ;

通过 snapshot.connectionState 可以获取当前异步请求的状态 , 可以在请求中显示进度条 , 请求后判定是否请求成功 , 如果出错 , 则显示报错信息 , 如果请求成功 , 则显示请求成功的信息 ;

无论怎样 , 最终要返回一个 Widget 组件 ;

FutureBuilder 构造函数完整代码示例 :

代码语言:javascript
复制
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(

        appBar: AppBar(
          title: Text("HTTP Get 请求"),
        ),

        // 线性布局 列
        body: FutureBuilder<CommonModel>(
          // 设置异步调用的方法
          future: httpGet(),

          /// 接收如下类型的对象
          /// typedef AsyncWidgetBuilder<T> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot);
          builder: (BuildContext context, AsyncSnapshot<CommonModel> snapshot){
            /// 判断 AsyncSnapshot 的连接状态
            switch(snapshot.connectionState){

              case ConnectionState.none:
                return Text("未连接");

              case ConnectionState.waiting:
                /// 返回一个进度条
                return Center(child: CircularProgressIndicator(),);

              case ConnectionState.active:
                /// 激活状态 , 返回一个进度条
                return Text("");

              case ConnectionState.done:
                /// 请求结束 , 如果出现错误 , 则返回错误信息
                /// 如果请求成功 , 返回从网络中请求的数据
                if(snapshot.hasError) {
                  return Text("请求失败 , 报错信息 : ${snapshot.error}", style: TextStyle(color: Colors.red),);
                } else {
                  return Text("请求成功 , 获取信息 : ${snapshot.data?.url}", style: TextStyle(color: Colors.green),);
                }

            }
          },
        ),
      ),
    );
  }

二、处理 Flutter 中的中文乱码


数据是以 UTF-8 格式进行编码的 , 只能以 UTF-8 格式进行解码 ;

创建 Utf8Decoder 解码器 ,

代码语言:javascript
复制
    /// 处理中文乱码
    Utf8Decoder utf8decoder = Utf8Decoder();

调用解码器的 convert 方法 , 传入原始的二进制数据 , 注意是字节数组类型的数据 ;

代码语言:javascript
复制
    /// 将二进制 Byte 数据以 UTF-8 格式编码 , 获取编码后的字符串
    String responseString = utf8decoder.convert(response.bodyBytes);

得到的返回值就是编码正确的字符串文本信息 ;

完整代码示例 :

代码语言:javascript
复制
  /// 调用 Http Get 方法 , 获取服务器的 json 数据
  Future<CommonModel> httpGet() async {
    //var url = Uri.parse('https://jsonplaceholder.typicode.com/posts/1');
    var url = Uri.parse('https://www.devio.org/io/flutter_app/json/test_common_model.json');

    // 异步请求 , 获取远程服务器信息
    final response = await http.get(url);

    /// 处理中文乱码
    Utf8Decoder utf8decoder = Utf8Decoder();
    /// 将二进制 Byte 数据以 UTF-8 格式编码 , 获取编码后的字符串
    String responseString = utf8decoder.convert(response.bodyBytes);

    // 将 json 字符串信息转为 Map<String, dynamic> 类型的键值对信息
    Map<String, dynamic> jsonMap = json.decode(responseString);
    return CommonModel.fromJson(jsonMap);
  }

三、完整代码示例


代码语言:javascript
复制
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

/// json 序列化 , 反序列化 包
import 'dart:convert';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  /// HTTP GET 返回值
  String httpGetResult = "";

  /// 调用 Http Get 方法 , 获取服务器的 json 数据
  Future<CommonModel> httpGet() async {
    //var url = Uri.parse('https://jsonplaceholder.typicode.com/posts/1');
    var url = Uri.parse('https://www.devio.org/io/flutter_app/json/test_common_model.json');

    // 异步请求 , 获取远程服务器信息
    final response = await http.get(url);

    /// 处理中文乱码
    Utf8Decoder utf8decoder = Utf8Decoder();
    /// 将二进制 Byte 数据以 UTF-8 格式编码 , 获取编码后的字符串
    String responseString = utf8decoder.convert(response.bodyBytes);

    // 将 json 字符串信息转为 Map<String, dynamic> 类型的键值对信息
    Map<String, dynamic> jsonMap = json.decode(responseString);
    return CommonModel.fromJson(jsonMap);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(

        appBar: AppBar(
          title: Text("HTTP Get 请求"),
        ),

        // 线性布局 列
        body: FutureBuilder<CommonModel>(
          // 设置异步调用的方法
          future: httpGet(),

          /// 接收如下类型的对象
          /// typedef AsyncWidgetBuilder<T> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot);
          builder: (BuildContext context, AsyncSnapshot<CommonModel> snapshot){
            /// 判断 AsyncSnapshot 的连接状态
            switch(snapshot.connectionState){

              case ConnectionState.none:
                return Text("未连接");

              case ConnectionState.waiting:
                /// 返回一个进度条
                return Center(child: CircularProgressIndicator(),);

              case ConnectionState.active:
                /// 激活状态 , 返回一个进度条
                return Text("");

              case ConnectionState.done:
                /// 请求结束 , 如果出现错误 , 则返回错误信息
                /// 如果请求成功 , 返回从网络中请求的数据
                if(snapshot.hasError) {
                  return Text("请求失败 , 报错信息 : ${snapshot.error}", style: TextStyle(color: Colors.red),);
                } else {
                  return Text("请求成功 , 获取信息 : ${snapshot.data?.url}", style: TextStyle(color: Colors.green),);
                }

            }
          },
        ),
      ),
    );
  }
}

class CommonModel {
  final String? icon;
  final String? title;
  final String? url;
  final String? statusBarColor;
  final bool? hideAppBar;

  CommonModel({this.icon, this.title, this.url, this.statusBarColor, this.hideAppBar});

  factory CommonModel.fromJson(Map<String, dynamic> json) {
    return CommonModel(
      icon: json['icon'],
      title: json['title'],
      url: json['url'],
      statusBarColor: json['statusBarColor'],
      hideAppBar: json['hideAppBar'],
    );
  }
}

执行结果 :

在这里插入图片描述
在这里插入图片描述

四、相关资源


参考资料 :

重要的专题 :

博客源码下载 :

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、FutureBuilder 简介
  • 二、处理 Flutter 中的中文乱码
  • 三、完整代码示例
  • 四、相关资源
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档