9.8 新商品栏、上下拉刷新
实现步骤:
第 1 步:安装插件 pull_to_refresh
1
| flutter pub add pull_to_refresh
|
第 2 步:main 配置插件
lib/main.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return ScreenUtilInit( ... builder: () { return RefreshConfiguration( headerBuilder: () => const ClassicHeader(), footerBuilder: () => const ClassicFooter(), hideFooterWhenNotFull: true, headerTriggerDistance: 80, maxOverScrollExtent: 100, footerTriggerDistance: 150, child: GetMaterialApp( title: 'Flutter Demo',
... ), ); }, ); }
|
第 3 步:控制器
lib/pages/goods/home/controller.dart
1 2 3 4 5 6 7 8
| final RefreshController refreshController = RefreshController( initialRefresh: true, );
int _page = 1;
final int _limit = 20;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
Future<bool> _loadNewsSell(bool isRefresh) async { var result = await ProductApi.products(ProductsReq( page: isRefresh ? 1 : _page, prePage: _limit, ));
if (isRefresh) { _page = 1; newProductProductList.clear(); }
if (result.isNotEmpty) { _page++;
newProductProductList.addAll(result); }
return result.isEmpty; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| void onLoading() async { if (newProductProductList.isNotEmpty) { try { var isEmpty = await _loadNewsSell(false);
if (isEmpty) { refreshController.loadNoData(); } else { refreshController.loadComplete(); } } catch (e) { refreshController.loadFailed(); } } else { refreshController.loadNoData(); } update(["home_news_sell"]); }
|
1 2 3 4 5 6 7 8 9 10
| void onRefresh() async { try { await _loadNewsSell(true); refreshController.refreshCompleted(); } catch (error) { refreshController.refreshFailed(); } update(["home_news_sell"]); }
|
1 2 3 4 5 6
| @override void onClose() { super.dispose(); refreshController.dispose(); }
|
第 4 步:刷新底部组件
lib/common/components/refresher.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import 'package:flutter/cupertino.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../index.dart';
class SmartRefresherFooterWidget extends StatelessWidget { final double? height;
final double? iconSize;
const SmartRefresherFooterWidget({ Key? key, this.iconSize, this.height, }) : super(key: key);
@override Widget build(BuildContext context) { return ClassicFooter( height: height ?? 60 + MediaQuery.of(context).padding.bottom + 30, loadingIcon: const CupertinoActivityIndicator().tight( width: iconSize ?? 25, height: iconSize ?? 25, ), outerBuilder: (child) => child.center().height(height ?? 60), ); } }
|
第 5 步:视图
lib/pages/goods/home/view.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| Widget _buildNewSell() { return GetBuilder<HomeController>( id: "home_news_sell", builder: (_) { return SliverGrid( delegate: SliverChildBuilderDelegate( (BuildContext context, int position) { var product = controller.newProductProductList[position]; return ProductItemWidget( product, imgHeight: 170.w, ); }, childCount: controller.newProductProductList.length, ), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: AppSpace.listRow, crossAxisSpacing: AppSpace.listItem, childAspectRatio: 0.8, ), ) .sliverPadding(bottom: AppSpace.page) .sliverPaddingHorizontal(AppSpace.page); }, ); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Widget _buildView() { return CustomScrollView( slivers: [ ...
controller.newProductProductList.isNotEmpty ? BuildListTitle( title: LocaleKeys.gHomeNewProduct.tr, onTap: () => controller.onAllTap(false), ).sliverToBoxAdapter().sliverPaddingHorizontal(AppSpace.page) : const SliverToBoxAdapter(), _buildNewSell(), ], ); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @override Widget build(BuildContext context) { return GetBuilder<HomeController>( init: Get.find<HomeController>(), id: "home", builder: (_) { return Scaffold( appBar: _buildAppBar(), body: SmartRefresher( controller: controller.refreshController, enablePullUp: true, onRefresh: controller.onRefresh, onLoading: controller.onLoading, footer: const SmartRefresherFooterWidget(), child: _buildView(), ), ); }, ); }
|
SmartRefresher
实现上下拉效果,child
子元素必须是一个 ScrollView
可滚动组件
提交代码到 git