如何将硬编码Flutter widget改造为支持函数参数的可复用模块化组件
实现方案
核心改造思路
你要实现的是Flutter列表类组件的通用封装逻辑,只需要给自定义组件暴露列表项构建函数入参,把内部固定的列表项渲染逻辑替换为外部传入的逻辑即可,具体改动如下:
- 给
PageOne组件新增两个必传参数:
indexCount:列表总项数,直接传给SliverChildBuilderDelegate的childCount属性itemBuilder:类型为Widget Function(BuildContext context, int index),由外部使用时传入,接收当前上下文和下标参数,返回对应下标的列表项Widget
- 将
SliverChildBuilderDelegate内部固定的列表项代码,替换为调用传入的itemBuilder方法
完整改造后代码
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:easy_refresh/easy_refresh.dart'; // 提前定义builder类型,让代码可读性更高 typedef SliverItemBuilder = Widget Function(BuildContext context, int index); class PageOne extends StatelessWidget { final int indexCount; // 列表项构建函数入参 final SliverItemBuilder itemBuilder; // 可按需扩展下拉刷新、上拉加载的回调入参,适配不同场景的交互逻辑 final Future<void> Function()? onRefresh; final Future<void> Function()? onLoad; const PageOne({ Key? key, required this.indexCount, required this.itemBuilder, this.onRefresh, this.onLoad, }) : super(key: key); @override Widget build(BuildContext context) { return SafeArea( child: Row( children: [ const SizedBox(width: 40.0), Consumer(builder: (context, ref, child) { return Expanded( child: EasyRefresh.custom( onRefresh: onRefresh, onLoad: onLoad, slivers: [ SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { // 直接调用外部传入的构建函数生成对应下标的列表项 return itemBuilder(context, index); }, childCount: indexCount, ), ), ], ), ); }), ], ), ); } }
使用示例
改造完成后可以在任意场景传入不同的参数复用组件,示例如下:
// 场景1:渲染蓝色卡片列表 PageOne( indexCount: 10, onRefresh: () async => print('触发下拉刷新'), itemBuilder: (context, index) { return Card( margin: const EdgeInsets.all(15), child: Container( color: Colors.blue[100 * (index % 9 + 1)], height: 80, alignment: Alignment.center, child: Text( '场景1 项 $index', style: const TextStyle(fontSize: 30), ), ), ); }, ) // 场景2:渲染纯文本列表 PageOne( indexCount: 20, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(20), child: Text( '场景2 第$index项', style: const TextStyle(fontSize: 16, color: Colors.red), ), ); }, )
内容的提问来源于stack exchange,提问作者RobbB
相关产品推荐
相关产品推荐

