Flutter实战视频-移动电商-18.首页_火爆专区后台接口调试
18.首页_火爆专区后台接口调试
博客地址:https://jspang.com/detailed?id=53#toc279
楼层结束之后有个火爆专区。到底部有个上拉加载的效果
lib/config/service_url.dart
首先找到我们的接口配置文件,增加接口的配置
lib/service/service_method.dart
复制原来的放进行修改
最终定义完的方法:
home_page.dart测试接口
我们在initState方法里面调用接口返回数据,并print打印出我们的数据
放在这里调用一下:
运行 查看测试效果
提取接口的方法
这两个方法几乎是一样的 ,所以我们单独做一个公共的方法
公共的方法
这样我们火爆专区的接口就可以使用通用的request的方法了。主要事项:这里一定要记住给Container里面加一个Text的widget。然后title随便给取个值,因为这如果不返回任何的widget的话控制台会输出一些错误。
查看效果:
也是可以调通的
改造获取首页所有数据的方法
我们主要用到方法名和传递的参数
改造之后的请求。把请求的方法封装成request方法 传递两个参数,参数1是请求的接口名称,参数2是请求传递的参数。
改造之后的,数据正常加载出来了
火爆专区的请求
最终代码:
import 'package:flutter/material.dart';
import '../service/service_method.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'dart:convert';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:url_launcher/url_launcher.dart'; class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
} class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin{ @override
bool get wantKeepAlive => true; @override
void initState() {
super.initState();
print('');
} String homePageContent='正在获取数据';
@override
Widget build(BuildContext context) {
var formData={'lon':'115.02932','lat':'35.76189'};//传一个经纬度过去,防止恶意下单
return Scaffold(
appBar: AppBar(title: Text('百姓生活+')),
body: FutureBuilder(
future: request('homePageContent',formData:formData),
builder: (context, snapshot) {
if(snapshot.hasData){
var data=json.decode(snapshot.data.toString());
List<Map> swiper=(data['data']['slides'] as List).cast();
List<Map> navigatorList=(data['data']['category'] as List).cast();
String adPicture=data['data']['advertesPicture']['PICTURE_ADDRESS'];
String leaderImage=data['data']['shopInfo']['leaderImage'];
String leaderPhone=data['data']['shopInfo']['leaderPhone'];
List<Map> recommendList=(data['data']['recommend'] as List).cast();
String floor1Title=data['data']['floor1Pic']['PICTURE_ADDRESS'];
String floor2Title=data['data']['floor2Pic']['PICTURE_ADDRESS'];
String floor3Title=data['data']['floor3Pic']['PICTURE_ADDRESS'];
List<Map> floor1=(data['data']['floor1'] as List).cast();
List<Map> floor2=(data['data']['floor2'] as List).cast();
List<Map> floor3=(data['data']['floor3'] as List).cast(); return SingleChildScrollView(
child: Column(
children: <Widget>[
SwiperDiy(swiperDateList: swiper),
TopNavigator(navigatorList:navigatorList ,),
AdBanner(adPicture:adPicture),
LeaderPhone(leaderImage: leaderImage,leaderPhone: leaderPhone,),
Recommend(recommendList:recommendList),
FloorTitle(picture_address: floor1Title,),//楼层1的标题图片
FloorContent(floorGoodsList: floor1),
FloorTitle(picture_address: floor2Title,),//楼层1的标题图片
FloorContent(floorGoodsList: floor2),
FloorTitle(picture_address: floor3Title,),//楼层1的标题图片
FloorContent(floorGoodsList: floor3),
HotGoods()
],
),
);
}else{
return Center(child: Text('加载中....'));
}
},
),
);
}
}
//首页轮播插件
class SwiperDiy extends StatelessWidget {
final List swiperDateList;
//构造函数
SwiperDiy({this.swiperDateList}); @override
Widget build(BuildContext context) { // print('设备的像素密度:${ScreenUtil.pixelRatio}');
// print('设备的高:${ScreenUtil.screenWidth}');
// print('设备的宽:${ScreenUtil.screenHeight}'); return Container(
height: ScreenUtil().setHeight(),//
width:ScreenUtil().setWidth(),
child: Swiper(
itemBuilder: (BuildContext context,int index){
return Image.network("${swiperDateList[index]['image']}",fit: BoxFit.fill,);
},
itemCount: swiperDateList.length,
pagination: SwiperPagination(),
autoplay: true,
),
);
}
} class TopNavigator extends StatelessWidget {
final List navigatorList; TopNavigator({Key key, this.navigatorList}) : super(key: key); Widget _gridViewItemUI(BuildContext context,item){
return InkWell(
onTap: (){print('点击了导航');},
child: Column(
children: <Widget>[
Image.network(item['image'],width: ScreenUtil().setWidth()),
Text(item['mallCategoryName'])
],
),
);
}
@override
Widget build(BuildContext context) {
if(this.navigatorList.length>){
this.navigatorList.removeRange(,this.navigatorList.length);//从第十个截取,后面都截取掉
}
return Container(
height: ScreenUtil().setHeight(),//只是自己大概预估的一个高度,后续可以再调整
padding: EdgeInsets.all(3.0),//为了不让它切着屏幕的边缘,我们给它一个padding
child: GridView.count(
crossAxisCount: ,//每行显示5个元素
padding: EdgeInsets.all(5.0),//每一项都设置一个padding,这样他就不挨着了。
children: navigatorList.map((item){
return _gridViewItemUI(context,item);
}).toList(),
),
);
}
} class AdBanner extends StatelessWidget {
final String adPicture; AdBanner({Key key, this.adPicture}) : super(key: key); @override
Widget build(BuildContext context) {
return Container(
child: Image.network(adPicture),
);
}
} //店长电话模块
class LeaderPhone extends StatelessWidget {
final String leaderImage;//店长图片
final String leaderPhone;//店长电话 LeaderPhone({Key key, this.leaderImage,this.leaderPhone}) : super(key: key); @override
Widget build(BuildContext context) {
return Container(
child: InkWell(
onTap: _launchURL,
child: Image.network(leaderImage),
),
);
} void _launchURL() async {
String url = 'tel:'+leaderPhone;
//String url = 'http://jspang.com';
if(await canLaunch(url)){
await launch(url);
}else{
throw 'url不能进行访问,异常';
}
}
} //商品推荐
class Recommend extends StatelessWidget {
final List recommendList; Recommend({Key key, this.recommendList}) : super(key: key); //商品标题
Widget _titleWidget(){
return Container(
alignment: Alignment.centerLeft,//局长靠左对齐
padding: EdgeInsets.fromLTRB(10.0, 2.0, , 5.0),//左上右下
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(width: 0.5,color: Colors.black12) //设置底部的bottom的边框,Black12是浅灰色
),
),
child: Text(
'商品推荐',
style:TextStyle(color: Colors.pink)
),
);
}
//商品单独项方法
Widget _item(index){
return InkWell(
onTap: (){},//点击事件先留空
child: Container(
height: ScreenUtil().setHeight(),//兼容性的高度 用了ScreenUtil
width: ScreenUtil().setWidth(),//750除以3所以是250
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border(
left: BorderSide(width: ,color: Colors.black12)//右侧的 边线的样式 宽度和 颜色
)
),
child: Column(
children: <Widget>[
Image.network(recommendList[index]['image']),
Text('¥${recommendList[index]['mallPrice']}'),
Text(
'¥${recommendList[index]['price']}',
style: TextStyle(
decoration: TextDecoration.lineThrough,//删除线的样式
color: Colors.grey//浅灰色
),
),
],
),
),
);
}
//横向列表方法
Widget _recommendList(){
return Container(
height: ScreenUtil().setHeight(),
child: ListView.builder(
scrollDirection: Axis.horizontal,//横向的
itemCount: recommendList.length,
itemBuilder: (context,index){
return _item(index);
},
),
);
} @override
Widget build(BuildContext context) {
return Container(
height: ScreenUtil().setHeight(),//列表已经设置为330了因为还有上面标题,所以要比330高,这里先设置为380
margin: EdgeInsets.only(top: 10.0),
child: Column(
children: <Widget>[
_titleWidget(),
_recommendList()
],
),
);
}
} //楼层标题
class FloorTitle extends StatelessWidget {
final String picture_address; FloorTitle({Key key, this.picture_address}) : super(key: key); @override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(8.0),
child: Image.network(picture_address),
);
}
} //楼层商品列表
class FloorContent extends StatelessWidget {
final List floorGoodsList; FloorContent({Key key, this.floorGoodsList}) : super(key: key); @override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
_firstRow(),
_otherGoods()
],
),
);
} Widget _firstRow(){
return Row(
children: <Widget>[
_goodsItem(floorGoodsList[]),
Column(
children: <Widget>[
_goodsItem(floorGoodsList[]),
_goodsItem(floorGoodsList[])
],
)
],
);
}
Widget _otherGoods(){
return Row(
children: <Widget>[
_goodsItem(floorGoodsList[]),
_goodsItem(floorGoodsList[])
],
);
}
Widget _goodsItem(Map goods){
return Container(
width: ScreenUtil().setWidth(),
child: InkWell(
onTap: (){print('点击了楼层商品');},
child: Image.network(goods['image']),
),
);
}
} //火爆专区 定义为动态的类
class HotGoods extends StatefulWidget {
@override
_HotGoodsState createState() => _HotGoodsState();
} class _HotGoodsState extends State<HotGoods> {
void initState() {
super.initState();
request('homePageBelowConten',formData:).then((val){
print(val);
});
}
@override
Widget build(BuildContext context) {
return Container(
child:Text('')
);
}
}
home_page.dart
import 'package:dio/dio.dart';
import 'dart:async';
import 'dart:io';
import '../config/service_url.dart'; //通用方法
Future request(url,{formData}) async{
try {
print('开始获取数据..............');
Response response;
Dio dio=new Dio();
dio.options.contentType=ContentType.parse('application/x-www-form-urlencoded');
//有参数的时候传参数,这里进行if判断
if(formData==null){
response=await dio.post(servicePath[url]);//不传参数
}else{
response=await dio.post(servicePath[url],data:formData);//传参数
} if(response.statusCode==){
print(response.data);
return response.data;
}else{
throw Exception('后端接口出现异常');
}
} catch (e) {
return print('ERROR:========>${e}');
}
} //获取首页主题内容 Future getHomePageContent() async{
try {
print('开始获取首页数据..............');
Response response;
Dio dio=new Dio();
dio.options.contentType=ContentType.parse('application/x-www-form-urlencoded');
var formData={'lon':'115.02932','lat':'35.76189'};//传一个经纬度过去,防止恶意下单
response=await dio.post(servicePath['homePageContent'],data:formData);
if(response.statusCode==){
print(response.data);
return response.data;
}else{
throw Exception('后端接口出现异常');
}
} catch (e) {
return print('ERROR:========>${e}');
}
}
//获得火爆专区的商品的方法
Future getHomePageBeloConten() async{
try {
print('开始获取火爆专区数据..............');
Response response;
Dio dio=new Dio();
dio.options.contentType=ContentType.parse('application/x-www-form-urlencoded');
int page=;//上拉加载数据 这里定义变量 页码
response=await dio.post(servicePath['homePageBelowConten'],data:page);
if(response.statusCode==){
print(response.data);
return response.data;
}else{
throw Exception('后端接口出现异常');
}
} catch (e) {
return print('ERROR:========>${e}');
}
}
service_method.dart
service_url.dart
const serviceUrl='http://test.baixingliangfan.cn/baixing/';
const servicePath={
'homePageContent':serviceUrl+'wxmini/homePageContent',//商店首页信息
'homePageBelowConten':serviceUrl+'wxmini/homePageBelowConten',//商城首页热卖商品
};
Flutter实战视频-移动电商-18.首页_火爆专区后台接口调试的更多相关文章
- Flutter实战视频-移动电商-19.首页_火爆专区界面布局编写
19.首页_火爆专区界面布局编写 看一下图片的效果 一个标题栏,下面是多行两列.里面可以用column布局,外面用Warp流式布局 有得小伙伴说这里可以用网格布局,网格布局的话还是有一定的效率问题.这 ...
- Flutter实战视频-移动电商-20.首页_火爆专区上拉加载效果
20.首页_火爆专区上拉加载效果 上拉加载的插件比较都.没有一个一枝独秀的 可以自定义酷炫的header和footer 一直在更新 推荐使用这个插件: https://github.com/xuelo ...
- Flutter实战视频-移动电商-09.首页_项目结构建立和获取数据
09.首页_项目结构建立和获取数据 在config下创建service_url.dart 用来配置我们后端接口的配置文件 一个变量存 接口地址,一个接口方法地址 所有后天请求数据的方法都放在这个文件夹 ...
- Flutter实战视频-移动电商-11.首页_屏幕适配方案讲解
11.首页_屏幕适配方案讲解 国人写的屏幕适配插件: https://github.com/OpenFlutter/flutter_screenutil 最新版本是0.5.1 在pubspec.yam ...
- Flutter实战视频-移动电商-13.首页_广告Banner组件制作
13.首页_广告Banner组件制作 主要是做这个小广告条. 其实就是读取一个图片做一个widget放到这里 使用stlessW快速生成 定义一个变量存放图片的url地址: 这样我们的广告条就写完了 ...
- Flutter实战视频-移动电商-15.首页_商品推荐模块编写
15.首页_商品推荐模块编写 商品推荐,我们做成可以横向滚动的 分析: 上面是标题,下面是ListView,里面是一个Column, column分三层,第一是图片,第二是价格,第三是市场价格 小细节 ...
- Flutter实战视频-移动电商-17.首页_楼层组件的编写技巧
17.首页_楼层组件的编写技巧 博客地址: https://jspang.com/post/FlutterShop.html#toc-b50 楼层的效果: 标题 stlessW快速生成: 接收一个St ...
- Flutter实战视频-移动电商-12.首页_GridView类别导航制作
12.首页_GridView类别导航制作 首页导航区的制作 外面用一个gridview来写.里面单独提出来 新建导航组件 还是在home_page.dart里面写代码 新建一个静态的组件: 快捷键写组 ...
- Flutter实战视频-移动电商-10.首页_FlutterSwiper轮播效果制作
10.首页_FlutterSwiper轮播效果制作 博客地址: https://jspang.com/post/FlutterShop.html#toc-5c2 flutter_swiper http ...
随机推荐
- IP分配及网段划分
1.IP我们先来了解一下3类常用的IP A类IP段 0.0.0.0 到127.255.255.255 B类IP段 128.0.0.0 到191.255.255.255 C类IP段 192.0.0. ...
- 调用Camera返回为空的分析及处理方法
前言 大家可能遇到了这种情况.调用Camera,然后指定自己定义的保存路径,结果返回的Intent为空.我们来分析一下原因. 分析 首先看Camera的部分逻辑,在源代码中的Camera.java的d ...
- ReboletricSample工程搭建
受到 Just Say No to More End-to-End Tests 文章链接:http://googletesting.blogspot.tw/2015/04/just-say-no-t ...
- linux的su和sudo(转载)
来源:http://www.jb51.net/LINUXjishu/12713.html 一. 使用 su 命令临时切换用户身份 1.su 的适用条件和威力 su命令就是切换用户的工具,怎么理解呢?比 ...
- 实例具体解释:反编译Android APK,改动字节码后再回编译成APK
本文具体介绍了怎样反编译一个未被混淆过的Android APK,改动smali字节码后,再回编译成APK并更新签名,使之可正常安装.破译后的apk不管输入什么样的username和password都能 ...
- Spring MVC之简单入门
一.Spring MVC简介: 1.什么是MVC 模型-视图-控制器(MVC)是一个众所周知的以设计界面应用程序为基础的设计模式.它主要通过分离模型(Model).视图(View)及控制器(Contr ...
- C/C++笔记之char *与wchar_t *的相互转换
char *和wchar_t *的相互转换,可使用标准库函数 size_t mbstowcs(wchar_t *wcstr, const char *mbstr, size_t count)和size ...
- DuiLib笔记之CDuiString的bug
在C/C++中,当使用==比较两个对象时,推荐的风格是将常量置前 例如 if (0 == variable) { ... } 但在DuiLib中,CDuiString存在一个bug:在用==进行比较时 ...
- Spring 实战 学习笔记(1)
Spring的核心 依赖注入 & 切面编程 1.创建应用组件之间协作的行为通常称为装配.(wiring) 2.Spring EL表达式.SEL是一种能在运行时构建复杂表达式,存取对象属性.对象 ...
- 我对Swift的几点疑问
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/caowenbin/article/details/31418773 Swift自问世 ...