flutter页面初始化加载http网络请求数据

本文介绍了在Flutter中如何在页面初始化时加载HTTP网络请求的数据,包括导入依赖、JSON转实体类、业务逻辑、UI编写、请求响应方法的实现以及调用请求并渲染UI的详细步骤。使用http包进行网络请求,并通过json转换为模型对象,然后在UI中动态展示数据。
部署运行你感兴趣的模型镜像

1、导入依赖

导入http包的依赖
这里的依赖版本可以参考以下地址
参考网址:packages-http

dependencies:
  flutter:
    sdk: flutter
  http: ^0.12.2

2、json转实体类

我们要通过网络请求来获取响应到的json数据,通常情况下要将响应到的数据封装成一个 model 对象,前端通过获得这个 model 来获取到所需要的数据。
json转换为实体类,我们可以使用自动生成工具,日常开发中也是这样操作的,因为都是固定格式的代码,使用自动工具可以极大简化开发流程。
关于具体的json转换为实体类,可以参考这篇文章 flutter自动转换json为实体类

之后我们会得到两个dart文件,此处的文件以个人生成为准,我生成的文件如下,文件结构可参考以上链接
SellBean.dart
SellBean.g.dart

3、业务逻辑

整体业务逻辑如下
发起请求,收到响应,封装数据,获得数据,展示数据
这是一个动态展示的过程,我们可以用两种方式实现:
1.使用StatefulWidget
2.使用StatelessWidget + 状态管理
这里我们使用第一种简单的方式,日常工作中多使用第二种方式

4、编写 UI

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:secondapp/dao/SellBean.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: new AppBar(
          centerTitle: true,
          backgroundColor: Color(0xFFFFFFFF),
          title: new Text(
            '预售专场',
            style: TextStyle(color: Colors.black, fontSize: 20.0),
          ),
        ),
        body: Center(
          //child: listView,
          child: new SellWidget(),
        ),
      ),
    );
  }
}

class SellWidget extends StatefulWidget {
  const SellWidget({
    Key key,
  });
  @override
  _SellWidgetState createState() => new _SellWidgetState();
}

class _SellWidgetState extends State<SellWidget> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: new Test(
        "Hello World"),
    );
  }

这套 UI 中我们定义了 SellWidget 这个 Widget,以实现动态处理,其中省略了大部分的控件代码,具体的项目代码在文章最后给出

5、请求响应方法

  static List<BikeModel> resBikeModels;
  
  Future<void> getdata() async {
    Map mapjson = {
      "version": "2.6.0",
      "userGuid": "3**************************49",
      "token": "91******************************d5",
      "clientId": "a7****************************07",
      "tabCityCode": "0517",
      "cityGuid": null,
      "action": "rent.merchant.fat.*****",
      "shopId": "30543"
    };
    var url = Uri.parse('https:/*********.com/api');
    var response = await http.post(
      url,
      body: json.encode(mapjson),
    );
    //print('Response status: ${response.headers}');
    String data = utf8.decode(response.bodyBytes);
    //var data = json.encode(resJson.jsonRes);
    //print('Response body: ${data}');
    SellBean sellBean = SellBean.fromJson(json.decode(data));
    // String resMap = sellBean.data.bikeModels[0].description;
    // List resMap =
    //     json.decode(response.body)["data"]["bikeModels"];
    // //print(resMap);
    //print(sellBean.data.bikeModels[0].pic);
  }

代码包裹在以下类中

class _SellWidgetState extends State<SellWidget> {}
  • 我们首先定义一个全局变量 List<BikeModel> resBikeModels
    这里的全局变量根据自身的返回值类型来确定,我这里返回的是链表
  • 我们的网络请求是异步操作,所以需要 async 关键字
  • 参数 mapjson 是请求体, 参数 url 是请求地址, http.post 会自动发起 post 请求,返回 json 数据
  • utf8.decode 编码为 utf8 格式字符串,SellBean.fromJson 将字符串编码为json格式并封装到实体类中
  • 注释的代码可以放开,通过打印相关数据检查响应是否正确,在VSCode控制台中,如果打印的数据过长,它会被截断

6、调用请求,渲染 UI

我们需要在页面加载时就发起异步请求,这就需要在 state 的生命周期中初始化数据,不同的生命周期可以执行不同的业务逻辑,生命周期非常重要,关于 state 生命周期可以参考 《flutter 实战》

class _SellWidgetState extends State<SellWidget> {
  @override
  void initState() {
    super.initState();

    print("这里执行了 initState 方法 ");
    getdata();
  }
  static List<BikeModel> resBikeModels;
  Future<void> getdata() async {
	...	
  }
}

重写 initState() 方法, 调用 getdata()方法
当加载该页面时,会先执行 initState() 方法执行初始化,此时页面中没有数据,是一个空白页,当请求到数据并返回后,会重新刷新 UI

7、全部代码

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:secondapp/dao/SellBean.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: new AppBar(
          centerTitle: true,
          backgroundColor: Color(0xFFFFFFFF),
          title: new Text(
            '预售专场',
            style: TextStyle(color: Colors.black, fontSize: 20.0),
          ),
        ),
        body: Center(
          //child: listView,
          child: new SellWidget(),
        ),
      ),
    );
  }
}

class SellWidget extends StatefulWidget {
  const SellWidget({
    Key key,
  });
  @override
  _SellWidgetState createState() => new _SellWidgetState();
}

class _SellWidgetState extends State<SellWidget> {
  static List<BikeModel> resBikeModels;

  @override
  void initState() {
    super.initState();

    print(" Future<void> main() async {");
    getdata();
  }

  Future<void> getdata() async {
    Map mapjson = {
      "version": "2.6.0",
      "userGuid": "3**************************49",
      "token": "91******************************d5",
      "clientId": "a7****************************07",
      "tabCityCode": "0517",
      "cityGuid": null,
      "action": "rent.merchant.fat.*****",
      "shopId": "30543"
    };
    var url = Uri.parse('https:/*********.com/api');
    var response = await http.post(
      url,
      body: json.encode(mapjson),
    );
    //print('Response status: ${response.headers}');
    String data = utf8.decode(response.bodyBytes);
    //var data = json.encode(resJson.jsonRes);
    //print('Response body: ${data}');
    SellBean sellBean = SellBean.fromJson(json.decode(data));
    // String resMap = sellBean.data.bikeModels[0].description;
    // List resMap =
    //     json.decode(response.body)["data"]["bikeModels"];
    // //print(resMap);
    print(sellBean.data.bikeModels[0].pic);
    setState(() {
      resBikeModels = sellBean.data.bikeModels;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: new ListView.builder(
            itemBuilder: (BuildContext context, int index) {
              BikeModel bike = resBikeModels[index];
              var hlIterm = Row(children: <Widget>[
                _leftImg(bike),
                Expanded(child: _rightColumn(bike))
              ], crossAxisAlignment: CrossAxisAlignment.start);
              return Column(
                children: <Widget>[
                  hlIterm,
                  Divider(
                    height: 1,
                    color: Colors.grey,
                  )
                ],
              );
            },
            itemCount: resBikeModels?.length ?? 0),
      ),
    );
  }

  Widget _leftImg(BikeModel bikeModel) {
    var img = new Image(
      image: NetworkImage(bikeModel.pic),
      width: 110.0,
      height: 100.0,
    );
    return _pd(img, l: 3, t: 10, r: 5, b: 10);
  }

  Widget _pd(Widget w, {double l, double t, double r, double b}) {
    return Padding(
      padding: EdgeInsets.fromLTRB(l ?? 0, t ?? 0, r ?? 0, b ?? 0),
      child: w,
    );
  }

  Widget _pda(Widget w, double a) {
    return Padding(
      padding: EdgeInsets.all(a),
      child: w,
    );
  }

  Widget _rightColumn(BikeModel bikeModel) {
    // 标题格式
    var titleStyle = TextStyle(color: Color(0xFF333333), fontSize: 14.0);
    // 描述格式
    var tagStyle = TextStyle(color: Color(0xFF999999), fontSize: 12.0);
    // 价格格式
    var priceStyle = TextStyle(
      color: Color(0xFFFF5000),
      fontSize: 24.0,
      fontWeight: FontWeight.w600,
    );

    var littlePriceStyle = TextStyle(
      color: Color(0xFFFF5000),
      fontSize: 14.0,
      fontWeight: FontWeight.w600,
    );

    var title = new Text(
      bikeModel.modelName,
      style: titleStyle,
      maxLines: 2,
      overflow: TextOverflow.ellipsis,
    );

    var tag = new Text(
      bikeModel.description,
      style: tagStyle,
    );

    var price = new Text(
      bikeModel.minPrice.toString(),
      style: priceStyle,
    );
    var priceRight = new Text('起', style: littlePriceStyle);
    var priceLeft = new Text('¥', style: littlePriceStyle);

    var deposit = Container(
        margin: EdgeInsets.only(left: 10),
        //边框设置
        decoration: new BoxDecoration(
          //背景
          color: Color(0xFFFF5000),
          //设置四周圆角 角度
          borderRadius: BorderRadius.all(Radius.circular(4.0)),
          //设置四周边框
          border: new Border.all(width: 1, color: Colors.red),
        ),
        child: new Text(
          '定金¥${bikeModel.deposit}',
          style: TextStyle(color: Color(0xFFFFFFFF)),
        ));

    var priceRow =
        Row(crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[
      priceLeft,
      price,
      priceRight,
      deposit,
    ]);
    return new Column(
      children: <Widget>[
        _pd(title, t: 10),
        _pd(tag, t: 10),
        _pd(priceRow, t: 30)
      ],
      crossAxisAlignment: CrossAxisAlignment.start,
    );
  }
}


您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值