Flutter-防京东商城项目-创建商品数据模型 、请求Api接口渲染热门商品 推荐商品 获取数据然后模型赋值-06

一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。

代码文档

Flutter防京东商城源码(1-10)链接

Flutter防京东商城源码(11-20)链接

Flutter防京东商城源码(21-30)链接

Flutter防京东商城源码(31-46)链接

效果:
请添加图片描述

本章目标:
1.创建商品数据模型
2.请求Api接口渲染热门商品
3.获取数据然后用模型赋值给猜你喜欢和热门推荐

第一步:编写全局接口文档

在这里插入图片描述

class Config{
  static String domain="http://jd.itying.com/";
}

第二步:修改图片轮播器接口 红色这句代码复制修改就可以了

说明:前面的章节接口是整个接口的,现在改为域名+路径
回到home页面进行导入。

import '../../config/Config.dart';

在这里插入图片描述

var api = '${Config.domain}api/focus';

第三步:开始编写模型

首先要先拿到接口先 http://jd.itying.com/api/plist?is_best=1 接口里面返回的数据模型是用于热门推荐和猜你喜欢的。

下面的内容是请求http://jd.itying.com/api/plist?is_best=1接口返回的数据,以防将来接口失效可以用下面的数据写成本地。

{"result":[{"_id":"5a0425bc010e711234661439","title":"磨砂牛皮男休闲鞋-有属性","cid":"5a042480010e711234661436","price":"688","old_price":"368","pic":"public\\upload\\RinsvExKu7Ed-ocs_7W1DxYO.png","s_pic":"public\\upload\\RinsvExKu7Ed-ocs_7W1DxYO.png_200x200.png"},{"_id":"5a0432f4010e71123466144c","title":"八匹狼羽绒服男--有属性","cid":"59f1e4f49bfd8f3bd030eed9","price":"288","old_price":"588","pic":"public\\upload\\agbBbaTUWBnWD7pYQOyJsNgJ.png","s_pic":"public\\upload\\agbBbaTUWBnWD7pYQOyJsNgJ.png_200x200.png"},{"_id":"5a07ef1fad8b300e28e2feb6","title":"联想(Lenovo)拯救者R720 15.6英寸游戏笔记本电脑","cid":"59f1e4919bfd8f3bd030eed6","price":"5345","old_price":"5345","pic":"public\\upload\\4i2vxChhbbz2qJMYEUGWw8g_.jpg","s_pic":"public\\upload\\4i2vxChhbbz2qJMYEUGWw8g_.jpg_200x200.jpg"},{"_id":"5a07ef64ad8b300e28e2feb8","title":"神舟(HASEE)战神K650D-G4D2 15.6英寸游戏笔记本电脑","cid":"59f1e4919bfd8f3bd030eed6","price":"4500","old_price":"4500","pic":"public\\upload\\iG8QZV0x7Thh8ZFKA3bCTER5.jpg","s_pic":"public\\upload\\iG8QZV0x7Thh8ZFKA3bCTER5.jpg_200x200.jpg"},{"_id":"5a07efe9ad8b300e28e2febb","title":"戴尔DELL灵越游匣Master15-R4645R 15.6英寸游戏笔记本电脑","cid":"59f1e4919bfd8f3bd030eed6","price":5677,"old_price":"6778","pic":"public\\upload\\YUv6N37Lriv7QK7WePQmyz-u.jpg","s_pic":"public\\upload\\YUv6N37Lriv7QK7WePQmyz-u.jpg_200x200.jpg"},{"_id":"5a080a05ad8b300e28e2fec1","title":"小米 红米Note5A 全网通版 2GB+16GB 香槟金 移动联通电信4G手机 双卡双待","cid":"59f1e4919bfd8f3bd030eed6","price":688,"old_price":"688","pic":"public\\upload\\1X_pUZmj8jQrVrWeiRtoa4Zx.jpg","s_pic":"public\\upload\\1X_pUZmj8jQrVrWeiRtoa4Zx.jpg_200x200.jpg"},{"_id":"5a080a9fad8b300e28e2fec6","title":"荣耀 畅玩6X 4GB 32GB 全网通4G手机 高配版 玫瑰金","cid":"59f1e4919bfd8f3bd030eed6","price":"789","old_price":"11111","pic":"public\\upload\\HSAZYh1vXyzn3kvpso4fs7iT.jpg","s_pic":"public\\upload\\HSAZYh1vXyzn3kvpso4fs7iT.jpg_200x200.jpg"},{"_id":"5a080ac5ad8b300e28e2fec7","title":"三星 Galaxy S7 edge(G9350)4GB+32GB 铂光金 移动联通电信4G手机","cid":"59f1e4919bfd8f3bd030eed6","price":1233,"old_price":"1322","pic":"public\\upload\\SesgdVtaD0RzW2B5NKXcTmEK.jpg","s_pic":"public\\upload\\SesgdVtaD0RzW2B5NKXcTmEK.jpg_200x200.jpg"},{"_id":"5a080b2ead8b300e28e2fec9","title":"小米Max2 全网通 4GB+64GB 金色 移动联通电信4G手机 双卡双待 6.44英寸大","cid":"59f1e4919bfd8f3bd030eed6","price":980,"old_price":"1211","pic":"public\\upload\\e7Z7qLeDpyFjNZMF2Ke1aiTE.jpg","s_pic":"public\\upload\\e7Z7qLeDpyFjNZMF2Ke1aiTE.jpg_200x200.jpg"},{"_id":"5a080c2ead8b300e28e2fed1","title":"锤子 坚果Pro 64GB 酒红色 全网通 移动联通电信4G手机 双卡双待 火热抢购中,","cid":"59f1e4919bfd8f3bd030eed6","price":1456,"old_price":"1468","pic":"public\\upload\\E8jnbcercoZGdllR3r9QN5aD.jpg","s_pic":"public\\upload\\E8jnbcercoZGdllR3r9QN5aD.jpg_200x200.jpg"}]}

拿到接口请求数据回来,然后打开 https://jsontodart.com/ 去自动生成Model 如果网站丢失就去百度输入JsonToDart 搜索。

模型名称为 ProductModel
在这里插入图片描述
在ProductModel模型中需要注意的是必须要修改一个地方,不然项目运行会崩溃
网上生成的模型多数是string类型,需要自己手动修改一下。
在这里插入图片描述

Object price;   //所有的类型都继承 Object

最终模型代码:


class ProductModel {
  List<ProductItemModel> result;

  ProductModel({this.result});

  ProductModel.fromJson(Map<String, dynamic> json) {
    if (json['result'] != null) {
      result = new List<ProductItemModel>();
      json['result'].forEach((v) {
        result.add(new ProductItemModel.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.result != null) {
      data['result'] = this.result.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class ProductItemModel {
  String sId;
  String title;
  String cid;
  Object price;
  String oldPrice;
  String pic;
  String sPic;

  ProductItemModel(
      {this.sId,
        this.title,
        this.cid,
        this.price,
        this.oldPrice,
        this.pic,
        this.sPic});

  ProductItemModel.fromJson(Map<String, dynamic> json) {
    sId = json['_id'];
    title = json['title'];
    cid = json['cid'];
    price = json['price'];
    oldPrice = json['old_price'];
    pic = json['pic'];
    sPic = json['s_pic'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['_id'] = this.sId;
    data['title'] = this.title;
    data['cid'] = this.cid;
    data['price'] = this.price;
    data['old_price'] = this.oldPrice;
    data['pic'] = this.pic;
    data['s_pic'] = this.sPic;
    return data;
  }
}

第四步:在首页中编写代码

1.导入模型

//热门跟推荐模型
import '../../model/ProductModel.dart';
// import 'package:review_flutter_app/model/ProductModel.dart';

2.创建接收model的数组

List _hotProductList = [];
List _bestProductList = [];

3.编写获取数据的方法

//获取猜你喜欢的数据
_getHotProductData() async {
  //编写接口
  var api = '${Config.domain}api/plist?is_hot=1';
  //请求数据
  var result = await Dio().get(api);
  //格式化数据
  var hotProductList = ProductModel.fromJson(result.data);
  //更新UI
  setState(() {
    this._hotProductList = hotProductList.result;
  });
}

//获取热门推荐的数据
_getBestProductData() async {
  //编写接口
  var api = '${Config.domain}api/plist?is_best=1';
  //请求数据
  var result = await Dio().get(api);
  //格式化数据
  var bestProductList = ProductModel.fromJson(result.data);
  //更新UI
  setState(() {
    this._bestProductList = bestProductList.result;
  });
}

第五步:程序启动时调用该方法

  _getHotProductData();
  _getBestProductData();

把上面的这两句代码写到下面的图片中,页面进来就请求接口,获取数据。
在这里插入图片描述

第六步:UI中赋值

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

源码

//热门商品
Widget _hotProductListWidget() {
  if (this._hotProductList.length > 0){
    return Container(
      height: ScreenAdaper.height(234),
      padding: EdgeInsets.all(ScreenAdaper.width(20)),
      child: ListView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: 10,
          itemBuilder: (context, index) {

            //处理图片
            String sPic = this._hotProductList[index].sPic;//——————————---------
            sPic = Config.domain + sPic.replaceAll('\\', '/');//——————————---------

            return Column(
              children: <Widget>[
                Container(
                  height: ScreenAdaper.height(140),
                  width: ScreenAdaper.width(140),
                  margin: EdgeInsets.only(right: ScreenAdaper.width(21)),
                  child: Image.network(
                    sPic,//——————————---------
                    fit: BoxFit.cover,
                  ),
                ),
                Container(
                  padding: EdgeInsets.only(top: ScreenAdaper.width(10)),
                  height: ScreenAdaper.height(44),
                  child: Text(//——————————---------
                    '¥${this._hotProductList[index].price}',//——————————---------
                     style: TextStyle(color: Colors.red),//——————————---------
                  ),//——————————---------
                ),
              ],
            );
          }),
    );
  }else{//——————————---------
    return Text('记载中....');//——————————---------
  }//——————————---------
}

热门推荐商品

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

Widget _recProductItemWidget() {

  var itemWidth = (ScreenAdaper.getScreenWidth() - 30) / 2; //计算容器宽度大小

  return Container(
    padding: EdgeInsets.all(10),
    child: Wrap(
      runSpacing: 10,
      spacing: 10,
      children: this._bestProductList.map((value){
        //图片
        String sPic=value.sPic;//—————————————————————————————————
        sPic=Config.domain+sPic.replaceAll('\\', '/');//—————————————————————————————————
        return Container(
          padding: EdgeInsets.all(10), //设置容器内边框为10
          width: itemWidth, //设置每个小容器的宽度
          decoration: BoxDecoration(
            //设置边框
            border: Border.all(
                color: Color.fromRGBO(233, 233, 233, 0.9), width: 1), //设置边框颜色跟变宽宽度
          ),
          child: Column(
            children: <Widget>[
              Container(
                //添加容器抱住图片,目的是可以设置图片与最大容器之前的宽高比
                width: double.infinity,
                child: AspectRatio(
                  aspectRatio: 1 / 1,
                  child: Image.network(
                    "${sPic}",//—————————————————————————————————
                    fit: BoxFit.cover,
                  ),
                ),
              ),
              Padding(
                //添加外边框抱住文字,目的是可以让文字与上面的图片有一个顶部距离20
                padding: EdgeInsets.only(top: ScreenAdaper.height(20)),
                child: Text(
                  "${value.title}",//—————————————————————————————————
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                  style: TextStyle(color: Colors.black54),
                ),
              ),
              Padding(
                //添加外边框抱住文字,目的是可以让文字与上面的图片有一个顶部距离20
                padding: EdgeInsets.only(top: ScreenAdaper.height(20)),
                child: Stack(
                  children: <Widget>[
                    Align(
                      alignment: Alignment.centerLeft, //控件在框的左边
                      child: Text(
                        "¥${value.price}",//—————————————————————————————————
                        style: TextStyle(color: Colors.red, fontSize: 16),
                      ),
                    ),
                    Align(
                      alignment: Alignment.centerRight, //控件在框的右边
                      child: Text(
                        "¥${value.oldPrice}",//—————————————————————————————————
                        style: TextStyle(
                          color: Colors.black54,
                          fontSize: 14,
                          decoration: TextDecoration.lineThrough, //文字中间加下划线
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        );
      }).toList(),
    ),
  );
}

4.不过要注意的是热门推荐UI的结构要修改一下
(下面的内容看看就可以了,不用写)

  @override
  Widget build(BuildContext context) {
    ScreenAdaper.init(context);

    // TODO: implement build
    return ListView(
      children: <Widget>[
        _swiperWidget(),
        SizedBox(
          height: ScreenAdaper.height(10),
        ),
        _titleWidge('猜你喜欢'),
        SizedBox(
          height: ScreenAdaper.height(10),
        ),
        _hotProductListWidget(),
        SizedBox(
          height: ScreenAdaper.height(10),
        ),
        _titleWidge('热门推荐'),
        _recProductItemWidget(),
      ],
    );
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯汉栩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值