Flutter点击孙组件WidgetBouquet时如何修改祖父BouquetScreenState的子组件
解决方案
核心逻辑为状态提升:将控制页面展示内容的状态放到顶层父组件BouquetScreenState中维护,通过回调函数逐层向下传递到WidgetBouquet组件,点击时触发回调修改父组件状态,即可完成页面组件切换。
步骤1:改造父组件BouquetScreenState
新增布尔类型状态变量标记当前展示的组件,同时定义切换方法作为回调向下传递:
class BouquetScreenState extends StatefulWidget { _BouquetScreenState createState() => _BouquetScreenState(); } class _BouquetScreenState extends State<BouquetScreenState> { // 新增状态变量:true展示GetProducts,false展示GetBouquets bool _showProducts = false; // 新增切换方法,供子组件回调触发 void _switchToProducts() { setState(() { _showProducts = true; }); } @override Widget build(BuildContext context) { return Container( // 根据状态变量动态渲染子组件 child: _showProducts ? GetProducts() // 将切换方法作为参数传给GetBouquets : GetBouquets(onBouquetTap: _switchToProducts), ); } }
步骤2:改造子组件GetBouquets
新增参数接收父组件传递的回调函数,再透传给孙组件WidgetBouquet:
class GetBouquets extends StatefulWidget { // 新增回调参数 final Function onBouquetTap; const GetBouquets({required this.onBouquetTap, Key? key}) : super(key: key); GetBouquetsState createState() => GetBouquetsState(); } class GetBouquetsState extends State<GetBouquets> { final ScrollController _scroll = ScrollController(); @override Widget build(BuildContext context) { return FutureBuilder<List<Bouquet>>( future: fetchBouquets(), builder: (context, snapshot) { if (!snapshot.hasData) return Center(child: CircularProgressIndicator()); else { return Container( child: Scrollbar( isAlwaysShown: true, controller: _scroll, child: GridView.builder( controller: _scroll, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, childAspectRatio: 0.8, crossAxisSpacing: 1, mainAxisSpacing: 25, ), itemCount: snapshot.data.length, itemBuilder: (BuildContext context, int index) { // 将回调透传给WidgetBouquet return WidgetBouquet( snapshot.data[index], onTap: widget.onBouquetTap ); } ), ), ); } }, ); } }
步骤3:改造孙组件WidgetBouquet
接收透传的回调函数,在点击事件中触发:
class WidgetBouquet extends StatefulWidget { final Bouquet data; // 新增回调参数 final Function onTap; const WidgetBouquet(this.data, {required this.onTap, Key? key}) : super(key: key); _BouquetState createState() => _BouquetState(); } class _BouquetState extends State<WidgetBouquet> { String? nom; String? error; @override Widget build(BuildContext context) { nom = widget.data.nom; return Container( child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( child: GestureDetector( // 点击时触发回调 onTap: () => widget.onTap(), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15.0), ), ), ), ), ], ), ); } }
如果需要从GetProducts切回GetBouquets,只需要参照相同逻辑,在父组件新增切换回GetBouquets的方法,传给GetProducts组件触发即可。
内容的提问来源于stack exchange,提问作者Asmoun
相关产品推荐
相关产品推荐

