12 Flutter仿京东商城项目 商品列表页面请求数据、封装Loading Widget、上拉分页加载更多
ProductList.dart
import 'package:flutter/material.dart';
import '../services/ScreenAdaper.dart';
import '../config/Config.dart';
import 'package:dio/dio.dart';
import '../model/ProductModel.dart';
import '../widget/LoadingWidget.dart'; class ProductListPage extends StatefulWidget {
Map arguments;
ProductListPage({Key key, this.arguments}) : super(key: key); _ProductListPageState createState() => _ProductListPageState();
} class _ProductListPageState extends State<ProductListPage> {
//通过事件打开侧边栏,需要全局声明一下:
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
//配置下拉加载更多:
ScrollController _scrollController = ScrollController();
//分页:
int _page = ;
//每一页有多少条数据:
int _pageSize = ;
//分页:
List _productList = [];
//排序:
String _sort = "";
//解决重复请求的问题:
bool flag = true; //是否有数据:
bool _hasMore = true; //初始化的时候获取的生命周期函数:
@override
void initState() {
super.initState();
_getProductListData();
//监听滚动条滚动事件:
_scrollController.addListener(() {
// _scrollController.position.pixels //获取滚动条滚动高度
// _scrollController.position.maxScrollExtent //获取页面滚动高度:
if (_scrollController.position.pixels >
_scrollController.position.maxScrollExtent - ) {
if (this.flag&&this._hasMore) {
_getProductListData();
}
}
});
} //获取商品列表的数据:
_getProductListData() async {
setState(() {
this.flag = false;
});
var api =
'${Config.domain}api/plist?cid=${widget.arguments["cid"]}&page=${_page}&sort=${this._sort}&pageSize=${_pageSize}';
var result = await Dio().get(api);
var productList = ProductModel.fromJson(result.data);
print(productList.result); if (productList.result.length < this._pageSize) {
setState(() {
this._productList.addAll(productList.result);
this._hasMore = false;
this.flag = true;
// this._productList = productList.result;
});
} else {
setState(() {
this._productList.addAll(productList.result);
this._page++;
this.flag = true;
// this._productList = productList.result;
});
}
}
//显示加载中的圈圈:
Widget _showMore(index){
if(this._hasMore){
return (index == this._productList.length - )? LoadingWidget() : Text('');
}else{
return (index == this._productList.length - )? Text("---暂无其他数据了--") : Text('');
}
} //商品列表:
Widget _productListWidget() {
if (this._productList.length > ) {
return Container(
padding: EdgeInsets.all(),
margin: EdgeInsets.only(top: ScreenAdaper.height()),
child: ListView.builder(
controller: _scrollController,
itemBuilder: (context, index) {
//处理图片:
String pic = this._productList[index].pic;
pic = Config.domain + pic.replaceAll('\\', '/');
//获得每一个元素:
return Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: ScreenAdaper.width(),
height: ScreenAdaper.height(),
child: Image.network("${pic}", fit: BoxFit.cover),
),
Expanded(
flex: ,
child: Container(
height: ScreenAdaper.height(),
margin: EdgeInsets.only(left: ),
// color: Colors.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"${this._productList[index].title}",
maxLines: ,
overflow: TextOverflow.ellipsis,
),
Row(
children: <Widget>[
Container(
height: ScreenAdaper.height(),
margin: EdgeInsets.only(right: ),
padding: EdgeInsets.fromLTRB(, , , ),
//注意:如果Container里面加上decoration属性,这个时候color属性必须放到BoxDecoration
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(),
// color:Color.fromRGBO(230, 230, 230, 0.9)
),
child: Text('4G'),
),
Container(
height: ScreenAdaper.height(),
margin: EdgeInsets.only(right: ),
padding: EdgeInsets.fromLTRB(, , , ),
//注意:如果Container里面加上decoration属性,这个时候color属性必须放到BoxDecoration
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(),
// color:Color.fromRGBO(230, 230, 230, 0.3)
),
child: Text('16G'),
)
],
),
Text("¥ ${this._productList[index].price}",
style:
TextStyle(color: Colors.red, fontSize: ))
],
),
),
)
],
),
Divider(
height: ,
),
this._showMore(index)
],
);
},
itemCount: this._productList.length,
),
);
} else {
return LoadingWidget();
}
} //筛选导航:
Widget _subHeaderWidget() {
return Positioned(
top: ,
height: ScreenAdaper.height(),
width: ScreenAdaper.width(),
child: Container(
height: ScreenAdaper.height(),
width: ScreenAdaper.width(),
// color: Colors.red,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: , color: Color.fromRGBO(, , , 0.9)))),
child: Row(
children: <Widget>[
Expanded(
flex: ,
child: InkWell(
child: Padding(
padding: EdgeInsets.fromLTRB(
, ScreenAdaper.height(), , ScreenAdaper.height()),
child: Text(
'综合',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red),
),
),
onTap: () {},
),
),
Expanded(
flex: ,
child: InkWell(
child: Padding(
padding: EdgeInsets.fromLTRB(
, ScreenAdaper.height(), , ScreenAdaper.height()),
child: Text('销量', textAlign: TextAlign.center),
),
onTap: () {},
),
),
Expanded(
flex: ,
child: InkWell(
child: Padding(
padding: EdgeInsets.fromLTRB(
, ScreenAdaper.height(), , ScreenAdaper.height()),
child: Text('价格', textAlign: TextAlign.center),
),
onTap: () {},
),
),
Expanded(
flex: ,
child: InkWell(
child: Padding(
padding: EdgeInsets.fromLTRB(
, ScreenAdaper.height(), , ScreenAdaper.height()),
child: Text('筛选', textAlign: TextAlign.center),
),
onTap: () {
_scaffoldKey.currentState.openEndDrawer();
},
),
)
],
),
),
);
} @override
Widget build(BuildContext context) {
ScreenAdaper.init(context);
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text('商品列表'),
actions: <Widget>[Text('')],
),
endDrawer: Drawer(
child: Container(
child: Text('实现筛选功能'),
),
),
// body: Text("${widget.arguments}"),
body: Stack(
children: <Widget>[_productListWidget(), _subHeaderWidget()],
),
);
}
}
Category.dart
import 'package:flutter/material.dart';
import '../../services/ScreenAdaper.dart';
import '../../config/Config.dart';
import 'package:dio/dio.dart';
import '../../model/CateModel.dart'; class CategoryPage extends StatefulWidget {
CategoryPage({Key key}) : super(key: key); _CategoryPageState createState() => _CategoryPageState();
} class _CategoryPageState extends State<CategoryPage>
with AutomaticKeepAliveClientMixin {
int _selectIndex = ;
List _leftCateList = [];
List _rightCateList = [];
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
_getLeftCateData();
} //左侧数据:
_getLeftCateData() async {
var api = '${Config.domain}api/pcate';
var result = await Dio().get(api);
var leftCateList = CateModel.fromJson(result.data);
setState(() {
this._leftCateList = leftCateList.result;
});
_getRightCateData(leftCateList.result[].sId);
} //右侧数据:
_getRightCateData(pid) async {
var api = '${Config.domain}api/pcate?pid=${pid}';
var result = await Dio().get(api);
var rightCateList = CateModel.fromJson(result.data);
print();
setState(() {
this._rightCateList = rightCateList.result;
});
} //左侧组件
Widget _leftCateWidget(leftWidth) {
if (this._leftCateList.length > ) {
return Container(
width: leftWidth,
height: double.infinity,
// color: Colors.red,
child: ListView.builder(
itemCount: this._leftCateList.length,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
InkWell(
onTap: () {
setState(() {
// setState(() {
_selectIndex = index;
this._getRightCateData(this._leftCateList[index].sId);
});
print(_selectIndex);
},
child: Container(
width: double.infinity,
height: ScreenAdaper.height(),
padding: EdgeInsets.only(top: ScreenAdaper.height()),
child: Text("${this._leftCateList[index].title}",
textAlign: TextAlign.center),
color: _selectIndex == index
? Color.fromRGBO(, , , 0.9)
: Colors.white,
),
),
Divider(height: ),
],
);
},
),
);
} else {
return Container(
width: leftWidth,
height: double.infinity,
);
}
} //右侧组件:
Widget _rightCateWidget(rightItemWidth, rightItemHeigth) {
if (this._rightCateList.length > ) {
return Expanded(
flex: ,
child: Container(
padding: EdgeInsets.all(),
height: double.infinity,
color: Color.fromRGBO(, , , 0.9),
// color: Colors.blue,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: ,
childAspectRatio: rightItemWidth / rightItemHeigth,
crossAxisSpacing: ,
mainAxisSpacing: ),
itemCount: this._rightCateList.length,
itemBuilder: (context, index) {
//处理图片:
String pic = this._rightCateList[index].pic;
pic = Config.domain + pic.replaceAll('\\', '/');
return InkWell(
child: Container(
// padding: EdgeInsets.all(ScreenAdaper.width(20)),
child: Column(
children: <Widget>[
AspectRatio(
aspectRatio: / ,
child: Image.network("${pic}", fit: BoxFit.cover),
),
Container(
height: ScreenAdaper.height(),
child: Text("${this._rightCateList[index].title}"),
)
],
),
),
onTap: (){
Navigator.pushNamed(context,'/productList',arguments: {
"cid":this._rightCateList[index].sId
});
}, );
},
),
),
);
} else {
return Expanded(
flex: ,
child: Container(
padding: EdgeInsets.all(),
height: double.infinity,
color: Color.fromRGBO(, , , 0.9),
child: Text('加载中...'),
));
}
} Widget build(BuildContext context) {
ScreenAdaper.init(context); //计算右侧GridView宽高比:
var leftWidth = ScreenAdaper.getScreenWidth() / ;
//右侧宽高=总宽度-左侧宽度-Gridview外层元素左右的Padding值-GridView中间的间距
var rightItemWidth =
(ScreenAdaper.getScreenWidth() - leftWidth - - ) / ;
rightItemWidth = ScreenAdaper.width(rightItemWidth);
var rightItemHeigth = rightItemWidth + ScreenAdaper.height(); return Row(
children: <Widget>[
_leftCateWidget(leftWidth),
_rightCateWidget(rightItemWidth, rightItemHeigth)
],
);
}
}
12 Flutter仿京东商城项目 商品列表页面请求数据、封装Loading Widget、上拉分页加载更多的更多相关文章
- 11 Flutter仿京东商城项目 商品列表页面二级筛选导航布局
ProductList.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper.dart'; imp ...
- 13 Flutter仿京东商城项目 商品列表筛选以及上拉分页加载更多
ProductList.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper.dart'; imp ...
- 18 Flutter仿京东商城项目 商品详情顶部tab切换 顶部下拉菜单 底部浮动导航
ProductContent.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper.dart'; ...
- 19 Flutter仿京东商城项目 商品详情 底部浮动导航布局 商品页面布局
效果: widget/JdButton.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper.da ...
- 38 Flutter仿京东商城项目 渲染结算页面商品数据
加群452892873 下载对应38课文件,运行方法,建好项目,直接替换lib目录 CartServices.dart import 'dart:convert'; import 'Storage.d ...
- 20 Flutter仿京东商城项目 商品详情 底部弹出筛选属性 以及筛选属性页面布局
ProductContentFirst.dart import 'package:flutter/material.dart'; import '../../widget/JdButton.dart' ...
- 21 Flutter仿京东商城项目 商品详情 请求接口渲染数据 商品属性数据渲染
加群452892873 下载对应21可文件,运行方法,建好项目,直接替换lib目录,在往pubspec.yaml添加上一下扩展. cupertino_icons: ^0.1.2 flutter ...
- 01-02 Flutter仿京东商城项目 功能分析、底部导航Tab切换以及路由配置、架构搭建:(Flutter仿京东商城项目 首页布局以及不同终端屏幕适配方案)
Flutter和Dart交流学习群:交流群:452892873 01Flutter仿京东商城项目 功能分析.底部导航Tab切换以及路由配置.架构搭建 02Flutter仿京东商城项目 首页布局以及不同 ...
- 16 Flutter仿京东商城项目 跳转到搜索页面实现搜索功能 以及搜索筛选
ProductList.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper.dart'; imp ...
随机推荐
- Flutter——Wrap组件(流式布局)
Wrap 可以实现流布局,单行的 Wrap 跟 Row 表现几乎一致,单列的 Wrap 则跟 Row 表现几乎一致.但 Row 与 Column 都是单行单列的,Wrap 则突破了这个限制,mainA ...
- Ubuntu系统---C++之VScode IDE 编译器安装
Ubuntu系统---C++之VScode IDE 编译器安装 简单了解了一下VScode,直观印象:安装包很小(不像VS那么大占用十G左右).跨平台.小巧.可以编译C++ / java / pyth ...
- 第93题:复原IP地址
一. 问题描述 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式. 示例: 输入: "25525511135" 输出: ["255.255.11.135 ...
- JavaEE企业面试问题之Java基础部分
1. Java基础部分 1.1 Java中的方法覆盖(Override)和方法重载(Overload)是什么意思? 重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不 ...
- django.db.utils.OperationalError: (1050, "Table 'article_category' already exists")
(转自:https://blog.csdn.net/huanhuanq1209/article/details/77884014) 执行manage.py makemigrations 未提示错误信息 ...
- 自己实现sizeof+大小端测试
#define my_sizeof(type) ((char *)(&type+1)-(char*)(&type)) 同时大小端测试 如下 #include <stdio.h&g ...
- Codeforces Round #551 (Div. 2) F. Serval and Bonus Problem (DP/FFT)
yyb大佬的博客 这线段期望好神啊... 还有O(nlogn)FFTO(nlogn)FFTO(nlogn)FFT的做法 Freopen大佬的博客 本蒟蒻只会O(n2)O(n^2)O(n2) CODE ...
- 用HTML5里的window.postMessage在两个网页间传递数据
说明 window.postMessage()方法可以安全地实现Window对象之间的跨域通信.例如,在一个页面和它生成的弹出窗口之间,或者是页面和嵌入其中的iframe之间. 通常情况下,不同页面上 ...
- Gradle 如何打包 Spring Boot 如何不添加版本代码
在 Gradle 中如何在打包的 Jar 中不包含版本代码? 在 bootJar 中,使用下面的代码进行打包不包含版本代码. archiveFileName = "${archiveBase ...
- [Luogu] 网络
https://www.luogu.org/problemnew/show/P3250 树链剖分 + 线段树 + 优先队列 要求未被影响的请求中最大的 所以每次将每条路径在整棵树上的补集的每个节点的优 ...