You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 17:54:07