Flutter实战视频-移动电商-43.详细页_补充首页跳转到详细页
43.详细页_补充首页跳转到详细页
首页轮播点击到详细页
修改我们轮播这里的代码:SwiperDiy这个类这里的代码
return InkWell(
onTap: (){
Application.router.navigateTo(context, '/detail?id=${swiperDateList[index]['goodsId']}');
},
child: Image.network("${swiperDateList[index]['image']}",fit: BoxFit.fill,),
);
展示效果:
商品推荐的跳转
_item方法增加了必须的参数context对象
_recommendList
点击也可以进行跳转
楼层的点击效果
方法:_goodsItem
发现上面的都没有传入context的值,所以我们都需要传入context对象
这些地方都要接收传入的context参数
楼层也实现了跳转
最终代码:
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';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import '../routers/application.dart'; class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
} class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin{ int page=;
List<Map> hotGoodsList=[];
GlobalKey<RefreshFooterState> _footerkey=new GlobalKey<RefreshFooterState>();
@override
bool get wantKeepAlive => true; @override
void initState() {
super.initState();
//_getHotGoods();
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 EasyRefresh(
refreshFooter: ClassicsFooter(
key: _footerkey,
bgColor: Colors.white,//背景颜色
textColor: Colors.pink,//粉红色
moreInfoColor: Colors.white,
showMore: true,
noMoreText: '',//具体也不知道到没到底 所以这里直接设置为空就不再显示了
moreInfo: '加载中',
loadReadyText: '上拉加载......',//网上拉 显示的文字
),
child: ListView(
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()
],
),
loadMore: () async {
print('开始加载更多....');
var formData={'page',page};
await request('homePageBelowConten',formData:formData).then((val){
var data=json.decode(val.toString());
List<Map> newGoodsList=(data['data'] as List).cast();
//把新的列表加到老的列表里面
setState(() {
hotGoodsList.addAll(newGoodsList);
page++;
});
});
},
);
}else{
return Center(child: Text('加载中....'));
}
},
),
);
}
//获取热销商品的数据
// void _getHotGoods(){
// var formData={'page',page};
// request('homePageBelowConten',formData:formData).then((val){
// var data=json.decode(val.toString());
// List<Map> newGoodsList=(data['data'] as List).cast();
// //把新的列表加到老的列表里面
// setState(() {
// hotGoodsList.addAll(newGoodsList);
// page++;
// });
// });
// }
//火爆专区的标题
Widget hotTitle = Container(
margin: EdgeInsets.only(top:10.0),//上边距
alignment: Alignment.center,//居中对齐
color: Colors.transparent,
padding: EdgeInsets.all(5.0),
child: Text('火爆专区'),
); Widget _wrapList(){
if(hotGoodsList.length!=){
List<Widget> listWidget=hotGoodsList.map((val){
return InkWell(
onTap: (){
Application.router.navigateTo(context, '/detail?id=${val['goodsId']}');
},
child: Container(
width: ScreenUtil().setWidth(),
color: Colors.white,
padding: EdgeInsets.all(5.0),//内边距
margin: EdgeInsets.only(bottom: 3.0),
child: Column(
children: <Widget>[
Image.network(val['image'],width: ScreenUtil().setWidth(),),//设置宽度防止超出边界
Text(
val['name'],
maxLines: ,//只有一行
overflow: TextOverflow.ellipsis,//超出显示省略号的形式
style: TextStyle(color: Colors.pink,fontSize: ScreenUtil().setSp()),
),
Row(
children: <Widget>[
Text('¥${val['mallPrice']}'),//商城价格
Text(
'¥${val['price']}',
style: TextStyle(color: Colors.black26,decoration: TextDecoration.lineThrough),//加上删除线的价格
)
],
)
],
),
),
);
}).toList();
return Wrap(
spacing: ,//每一行显示两列
children: listWidget,
);
}else{
return Text('');
}
} //组合火爆专区的标题和列表
Widget _hotGoods(){
return Container(
child: Column(
children: <Widget>[
hotTitle,
_wrapList()
],
),
);
} }
//首页轮播插件
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 InkWell(
onTap: (){
Application.router.navigateTo(context, '/detail?id=${swiperDateList[index]['goodsId']}');
},
child: 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(
physics: NeverScrollableScrollPhysics(),
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(context,index){
return InkWell(
onTap: (){
Application.router.navigateTo(context, '/detail?id=${recommendList[index]['goodsId']}');
},//点击事件先留空
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(context,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(context),
_otherGoods(context)
],
),
);
} Widget _firstRow(context){
return Row(
children: <Widget>[
_goodsItem(context,floorGoodsList[]),
Column(
children: <Widget>[
_goodsItem(context,floorGoodsList[]),
_goodsItem(context,floorGoodsList[])
],
)
],
);
}
Widget _otherGoods(context){
return Row(
children: <Widget>[
_goodsItem(context,floorGoodsList[]),
_goodsItem(context,floorGoodsList[])
],
);
}
Widget _goodsItem(BuildContext context,Map goods){
return Container(
width: ScreenUtil().setWidth(),
child: InkWell(
onTap: (){
Application.router.navigateTo(context, '/detail?id=${goods['goodsId']}');
},
child: Image.network(goods['image']),
),
);
}
}
home_page.dart
Flutter实战视频-移动电商-43.详细页_补充首页跳转到详细页的更多相关文章
- Flutter移动电商实战 --(43)详细页_补充首页跳转到详细页
首页轮播点击到详细页 修改我们轮播这里的代码:SwiperDiy这个类这里的代码 return InkWell( onTap: (){ Application.router.navigateTo(co ...
- Flutter实战视频-移动电商-05.Dio基础_引入和简单的Get请求
05.Dio基础_引入和简单的Get请求 博客地址: https://jspang.com/post/FlutterShop.html#toc-4c7 第三方的http请求库叫做Dio https:/ ...
- Flutter实战视频-移动电商-08.Dio基础_伪造请求头获取数据
08.Dio基础_伪造请求头获取数据 上节课代码清楚 重新编写HomePage这个动态组件 开始写请求的方法 请求数据 .但是由于我们没加请求的头 所以没有返回数据 451就是表示请求错错误 创建请求 ...
- Flutter实战视频-移动电商-64.会员中心_顶部头像UI布局
64.会员中心_顶部头像UI布局 会员中心的样式 member.dart 清除原来的代码生成一个基本的结构 默认返回一个scaffold脚手架工具,body里面布局使用ListView,这样不会出现纵 ...
- Flutter实战视频-移动电商-66.会员中心_编写ListTile通用方法
66.会员中心_编写ListTile通用方法 布局List里面嵌套一个ListTile的布局效果 里面有很多条记录,以后可能还会增加,所以这里我们做一个通用的组件 通用组件方法 这里使用Column布 ...
- Flutter实战视频-移动电商-65.会员中心_订单区域UI布局
65.会员中心_订单区域UI布局 我的订单区域 member.dart写我的标题的方法 布局使用瓦片布局 先做修饰,decoration颜色的背景,下边线的样式 //我的订单标题 Widget _or ...
- Flutter实战视频-移动电商-40.路由_Fluro的全局注入和使用方法
40.路由_Fluro的全局注入和使用方法 路由注册到顶层,使每个页面都可以使用,注册到顶层就需要在main.dart中 main.dart注册路由 注入 onGenerateRoute是Materi ...
- Flutter实战视频-移动电商-44.详细页_首屏自定义Widget编写
44.详细页_首屏自定义Widget编写 把详细页的图片.标题.编号和价格形成一个单独的widget去引用 详情页的顶部单独封装个插件 在pages下面新建detials_page的文件件并在里面新建 ...
- Flutter实战视频-移动电商-45.详细页_说明区域UI编写
45.详细页_说明区域UI编写 pages/details_page/details_expain.dart 详情页面引用组件 效果展示: 最终代码: import 'package:flutter/ ...
随机推荐
- caffe2--Install
Install Welcome to Caffe2! Get started with deep learning today by following the step by step guide ...
- 关闭和定时显示DIV
<script type="text/javascript"> $(function(){ $('#ad1').css('display','block'); }) f ...
- 第 1 章 第 2 题 空间敏感排序问题 位向量实现( bitset位向量 )
问题分析 在上篇文章中,给出了使用C语言中经典位运算符来实现位向量的方法.而本文,将介绍使用C++中的bitset容器来实现位向量的方法. 实现 // 请包含bitset头文件 #include &l ...
- 【转】安卓逆向实践5——IDA动态调试so源码
之前的安卓逆向都是在Java层上面的,但是当前大多数App,为了安全或者效率问题,会把一些重要功能放到native层,所以这里通过例子记录一下使用IDA对so文件进行调试的过程并对要点进行总结. 一. ...
- JS中小数如何转化为百分数并能四舍五入
<script type="text/javascript">//n表示百分数保留的位数 function toPercent(n){ n = n || 2; retu ...
- Go怎么获取当前时间? Go ARM64 vDSO优化之路
https://mzh.io/ Go ARM64 vDSO优化之路 2018-03-16 | Meng Zhuo 背景 Go怎么获取当前时间?问一个会Go的程序员,他随手就能写这个出来给你. imp ...
- Windows消息、绘图与多线程
有一个项目,一旦点下按钮后,用死循环不停的读数据,读出后立刻用可视化的方法显示.如果不采用多线程的方法,程序运行都正确,但无法关闭窗口,不清楚是窗口无法通过关闭按钮来接受Windows消息,还是接受了 ...
- 《打造Facebook》
王淮的<打造Facebook>一书不厚,花半天时间轻松读完.书中没有大段的说教,只有近乎流水的陈述.正如作者所说,打造Facebook这本书由巴克伯格来写再合适不过.可惜他至少在近几年内没 ...
- Block浅析一
1.在Block结构体中含有isa指针,这就证明了Block其实就是对象,并具有一般对象的所有功能. 2.Block是OC中的一种数据类型,在iOS开发中被广泛使用. 3.block的应用 (1)遍历 ...
- ubuntu12.04离线安装libjpeg62-dev
0:如果的电脑能连接上网络,用apt-get install安装最爽,我的情况是:公司电脑用的内网,访问不了外网,而且不让访问外网,安装软件只能用u盘拷进去再安装,所以我用如下方法 1:下载安装包,地 ...