flutter - 滚动控制器不适用于futurebuilder
问题描述
我有一个通过偏移量上传数据的 api 调用,我的目标是在用户向下滚动时加载 10 x 10,问题是我无法向下滚动并显示更多数据:这是我的片段:
class Body extends StatefulWidget {
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
HomeHeader(),
ProductsGridViewInfiniteScroll(),
],
),
);
}
}
这里的滚动控制器似乎不起作用:
class ProductsGridViewInfiniteScroll extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return ProductsGridViewInfiniteScrollState();
}
}
class ProductsGridViewInfiniteScrollState
extends State<ProductsGridViewInfiniteScroll> {
Future<ProductList> products;
int offset;
ScrollController _controller;
_scrollListener() {
if (_controller.offset >= _controller.position.maxScrollExtent &&
!_controller.position.outOfRange) {
setState(() {
offset += 10;
products = loadProductsByIdService(1, offset, 10);
});
}
}
@override
void initState() {
offset = 0;
products = loadProductsByIdService(1, offset, 10);
_controller = ScrollController();
_controller.addListener(_scrollListener);
super.initState();
}
Widget build(BuildContext context) {
return FutureBuilder<ProductList>(
future: products,
builder: (context, snapshot) {
if (snapshot.hasData) {
return GridView.builder(
controller: _controller,
itemCount: snapshot.data.products.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 4.0,
mainAxisSpacing: 10.0),
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (BuildContext ctx, index) {
return Container(
alignment: Alignment.center,
child: ProductCard(product: snapshot.data.products[index]),
);
});
} else {
return SizedBox();
}
});
}
}
Future<ProductList> loadProductsByIdService(serviceid, offset, limit) async {
var datamap = {'service_id': serviceid, 'offset': offset, 'limit': limit};
var data = json.encode(datamap);
ProductList products;
final response = await http.post(Uri.parse(PRODUCTS),
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
},
body: data,
encoding: Encoding.getByName("utf-8"));
if (response.body.isNotEmpty) {
if (response.statusCode == 200) {
products = ProductList.fromJson(json.decode(response.body));
}
} else {
throw Exception('echec de chargement des produits');
}
return products;
}
每次滚动到达屏幕底部时,我都想重建构建功能并更新产品变量,请提供帮助;
解决方案
看起来ClampingScrollPhysics是 Android 和BouncingScrollPhysics中滚动物理的默认行为。很可能您在 IOS 上运行,因此默认情况下您使用的是 BouncingScrollPhysics。如果是这种情况,请将您的 if 条件更改为:
_scrollListener() {
if (_controller.offset >= _controller.position.maxScrollExtent &&
_controller.position.outOfRange) {
_controller.jumpTo(0);
setState(() {
offset += 10;
products = getProducts(offset, limit);
});
}
}
当使用弹跳物理时,滚动通过 max scrolling extend 并且 outOfRange 变为 true。您需要将控制器偏移量重置回 0,因为它将继续多次调用侦听器,从而通过增加偏移量来跳过页面。
推荐阅读
- android - 发现人工制品的本机依赖项
- next.js - 使用 Netlify 部署 Next.js 网站
- c# - HttpContent.ReadAsStringAsync 导致请求挂起
- cordova - 如何使用适用于 Apache Cordova 的 cordova-android 定位最广泛的 Android 设备?
- java - 如何检查android studio中的日期是否更改?
- math - 如何从两个 3D 方向向量中获得 X 和 Y 旋转(零 Z 旋转)
- c - 不能在 C 中的 main() 之前声明 void 函数
- javascript - 具有单击功能的 addEventListener 不起作用
- botframework - 如何获取已发送消息 Bot Framework(团队频道)的消息 ID?
- jquery - 使菜单下拉集中在可访问性上