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

如何在Flutter的PageView组件间传递两个下拉按钮的数据?

问题:Flutter引导页中Page2下拉选择值传递给Page0的问题

我正在构建一个包含三个页面的引导功能:

  • Page0包含PageView Widget,通过widgets.add()方法加载Page1和Page2
  • Page1是欢迎页面
  • Page2包含两个下拉按钮,需要在onChanged触发后将选中值传递给Page0

Page0 代码

class Page0 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _Page0State();
}

class _Page0State extends State<Page0> {
  late UserPreferencesArguments? args;

  int currentPage = 0;
  static const _kDuration = const Duration(milliseconds: 500);
  static const _kCurve = Curves.ease;
  PageController pageController = PageController();
  final globalScaffoldKey = GlobalKey<ScaffoldState>();

  List<Widget> widgets = [];

  @override
  void initState() {
    super.initState();
    init();
  }

  init() async {
    widgets.add(Page1());
    widgets.add(Page2());
  }

  @override
  void dispose() {
    //pageController?.dispose();
    super.dispose();
  }

  @override
  void setState(fn) {
    if (mounted) super.setState(fn);
  }

  @override
  Widget build(BuildContext context) {
    args = ModalRoute.of(context)?.settings.arguments as UserPreferencesArguments?;

    return SafeArea(
      child: Scaffold(
        key: globalScaffoldKey,
        body: Stack(
          children: [
            Container(
              child: PageView(
                scrollDirection: Axis.horizontal,
                controller: pageController,
                children: widgets,
                onPageChanged: (i) {
                  currentPage = i;
                  setState(() {});
                },
              ),
            ),
            Positioned(
              child: Container(
                child: ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.black,
                    shadowColor: Colors.grey,
                  ),
                  onPressed: () {
                    if (currentPage == 1) {
                      updateAttributes(args?.aaa, args?.bbb);
                      Navigator.pushReplacementNamed(context, '/homepage');
                    } else {
                      pageController.nextPage(duration: _kDuration, curve: _kCurve);
                    }
                  },
                  child: Text(currentPage == 1 ? 'Finish' : "Next",),
                ),
              ),
            ),
          ],
        )
      ),
    );
  }

  updateAttributes(aaa, bbb) async {
    debugPrint('devid:  ${aaa}');
    debugPrint('devid:  ${bbb}');
  }

}

Page2 代码

class Page2 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _Page2State();
}

class _Page2State extends State<Page2> {

  String aaaImportValue = "";
  String? _valAAA;
  List _aaaList = ["1", "2" ];

  String bbbImportValue = "";
  String? _valBBB;
  List _bbbList = ["3", "4" ];

  @override
  void initState() {
    super.initState();
    init();
  }

  init() async {}

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
                    Container(
                      child: DropdownButton<String>(
                        hint: Text("Select").tr(),
                        value: _valAAA,
                        items: _aaaList.map((value) {
                          return DropdownMenuItem<String>(
                            child: Text(value),
                            value: value,
                          );
                        }).toList(),
                        onChanged: (String? value) {
                          setState(() {
                              _valAAA = value!;
                          });
                        },
                      ),
                    ),
                    Container(
                      child: DropdownButton<String>(
                        hint: Text("Select").tr(),
                        value: _valBBB,
                        items: _bbbList.map((value) {
                          return DropdownMenuItem<String>(
                            child: Text(value),
                            value: value,
                          );
                        }).toList(),
                        onChanged: (String? value) {
                          setState(() {
                            _valBBB = value!;
                          });
                        },
                      ),
                    ),
      ],
    );
  }
}

尝试过的无效方法

我尝试在下拉按钮的onChanged中通过路由跳转传参,但这样只会重新导航到Page0,无法把值传递给当前已存在的Page0实例:

onChanged: (String? value) {
    setState(() {
         _valBBB = value!;
         if(_valBBB != null){
             Navigator.pushNamed(context, "/Page0",
             arguments: UserPreferencesArguments(_valAAA, _valBBB));
         }
    });
},
解决方案

因为Page2是Page0中PageView的子组件,无需通过路由跳转传参,直接用回调函数即可实现值的传递,步骤如下:

  1. 修改Page2的StatefulWidget,添加回调参数
class Page2 extends StatefulWidget {
  // 定义回调函数,用于传递选中的两个值
  final Function(String? aaa, String? bbb)? onValuesChanged;

  const Page2({Key? key, this.onValuesChanged}) : super(key: key);

  @override
  State<StatefulWidget> createState() => new _Page2State();
}
  1. 在Page2的下拉按钮onChanged中触发回调
    更新两个下拉按钮的onChanged逻辑,每次选中值变化时调用回调把值传给Page0:
// AAA下拉按钮的onChanged
onChanged: (String? value) {
  setState(() {
    _valAAA = value!;
  });
  // 触发回调传递当前选中的两个值
  widget.onValuesChanged?.call(_valAAA, _valBBB);
},

// BBB下拉按钮的onChanged
onChanged: (String? value) {
  setState(() {
    _valBBB = value!;
  });
  // 触发回调传递当前选中的两个值
  widget.onValuesChanged?.call(_valAAA, _valBBB);
},
  1. 在Page0中初始化Page2时传入回调
    修改Page0的init方法,传入回调函数接收Page2传来的值并更新本地状态:
init() async {
  widgets.add(Page1());
  widgets.add(Page2(
    onValuesChanged: (aaa, bbb) {
      setState(() {
        // 保存Page2传递过来的值
        args = UserPreferencesArguments(aaa, bbb);
      });
    },
  ));
}
  1. 调整Page0的按钮逻辑和更新方法
    简化updateAttributes方法,直接使用本地保存的args值:
updateAttributes() async {
  debugPrint('aaa:  ${args?.aaa}');
  debugPrint('bbb:  ${args?.bbb}');
}

// 同时修改按钮的onPressed逻辑
onPressed: () {
  if (currentPage == 1) {
    updateAttributes();
    Navigator.pushReplacementNamed(context, '/homepage');
  } else {
    pageController.nextPage(duration: _kDuration, curve: _kCurve);
  }
},

其他可选方案

如果后续页面结构更复杂,也可以使用ValueNotifier或状态管理工具(如Provider)来实现跨组件状态共享,但对于当前的父子组件传值场景,回调函数是最直接高效的方式。

内容的提问来源于stack exchange,提问作者BradG

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:05:07