Flutter:如何将belt_controller的DropdownButton值传递到profile_reset_page
我创建了belt_controller_page.dart文件,在profile_reset_page(资料修改页)中调用belt_controller()即可显示下拉按钮。现在需要把belt_controller里DropdownButton的选中值传递到profile_reset_page。我试过修改belt_controller的onChanged方法,实例化profile_reset_page并传值,同时给profile_reset_page添加必填参数,但未成功。
原代码
belt_controller组件代码
class belt_controller extends StatefulWidget { const belt_controller({super.key}); @override State<belt_controller> createState() => _belt_controllerState(); } class _belt_controllerState extends State<belt_controller> { ///Belt Controllers List<String> dropdownList = ['white', 'blue', 'purple', 'brown', 'black']; String selectedDropdown = 'white'; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB(25, 5, 25, 5), child: Container( decoration: BoxDecoration( border: Border.all(color: Colors.grey, width: 1), color: Colors.grey[200], borderRadius: BorderRadius.circular(10), ), child: DropdownButton( hint: const Text('belt'), value: selectedDropdown, focusColor: Colors.grey, dropdownColor: Colors.grey.shade400, icon: const Icon(Icons.arrow_drop_down), isExpanded: true, underline: const SizedBox(), style: const TextStyle( color: Colors.black, fontSize: 17, ), items: dropdownList.map((String item) { return DropdownMenuItem<String>( child: Text(item), value: item, ); }).toList(), onChanged: (dynamic belt_value) { setState(() { selectedDropdown = belt_value; print(belt_value); }); }, ), ), ); } }
profile_reset_page页面代码
class profile_reset_page extends StatefulWidget { profile_reset_page({super.key}); @override State<profile_reset_page> createState() => _profile_reset_pageState(); } class _profile_reset_pageState extends State<profile_reset_page> { @override Widget build(BuildContext context) { return Scaffold( body: SizedBox( child: SafeArea( child: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ belt_controller(), const SizedBox(height: 20,), jiujitsuProfileButton( text: 'Change', TextColor: Colors.white, BackgroundColor: Colors.red[300], onTap: upDateUser, ), ] ), ), ), ), ); } }
我的尝试(未成功)
修改belt_controller中的onChanged方法:
onChanged: (dynamic belt_value) { setState(() { selectedDropdown = belt_value; print(belt_value); profile_reset_page(belt_value:belt_value); }); },
同时给profile_reset_page添加final belt_value和必填参数,但没有效果。
正确解决方案
你之前的错误在于在子组件里实例化父组件,完全违背了组件通信逻辑。正确做法是通过回调函数将选中值从子组件传递到父组件:
步骤1:修改belt_controller组件,添加回调参数
class belt_controller extends StatefulWidget { // 定义回调函数,用于传递选中值 final Function(String) onBeltSelected; // 可选:支持父组件传入初始选中值 final String initialValue; const belt_controller({ super.key, required this.onBeltSelected, this.initialValue = 'white', }); @override State<belt_controller> createState() => _belt_controllerState(); } class _belt_controllerState extends State<belt_controller> { late String selectedDropdown; List<String> dropdownList = ['white', 'blue', 'purple', 'brown', 'black']; @override void initState() { super.initState(); // 用父组件传入的初始值初始化 selectedDropdown = widget.initialValue; } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB(25, 5, 25, 5), child: Container( decoration: BoxDecoration( border: Border.all(color: Colors.grey, width: 1), color: Colors.grey[200], borderRadius: BorderRadius.circular(10), ), child: DropdownButton<String>( // 明确类型,避免dynamic hint: const Text('belt'), value: selectedDropdown, focusColor: Colors.grey, dropdownColor: Colors.grey.shade400, icon: const Icon(Icons.arrow_drop_down), isExpanded: true, underline: const SizedBox(), style: const TextStyle( color: Colors.black, fontSize: 17, ), items: dropdownList.map((String item) { return DropdownMenuItem<String>( child: Text(item), value: item, ); }).toList(), onChanged: (String? belt_value) { if (belt_value != null) { setState(() { selectedDropdown = belt_value; }); // 调用回调函数,将选中值传给父组件 widget.onBeltSelected(belt_value); } }, ), ), ); } }
步骤2:修改profile_reset_page,接收子组件传递的值
class profile_reset_page extends StatefulWidget { const profile_reset_page({super.key}); @override State<profile_reset_page> createState() => _profile_reset_pageState(); } class _profile_reset_pageState extends State<profile_reset_page> { // 存储子组件传递过来的选中值 String? selectedBelt; @override Widget build(BuildContext context) { return Scaffold( body: SizedBox( child: SafeArea( child: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ belt_controller( // 传入回调函数,接收子组件的选中值 onBeltSelected: (value) { setState(() { selectedBelt = value; }); print('父组件收到选中腰带:$value'); }, // 可选:设置初始选中值 initialValue: 'blue', ), const SizedBox(height: 20,), jiujitsuProfileButton( text: 'Change', TextColor: Colors.white, BackgroundColor: Colors.red[300], onTap: upDateUser, ), ], ), ), ), ), ); } // 提交时可直接使用selectedBelt变量 void upDateUser() { if (selectedBelt != null) { print('要提交的腰带值:$selectedBelt'); // 执行更新用户资料的逻辑 } } }
说明
- 回调函数是Flutter中子父组件通信的常用方式,子组件通过调用父组件传入的函数传递数据。
- 禁止在子组件中实例化父组件,这会创建新的页面实例,而非更新当前页面状态。
- 明确类型(如用
String?代替dynamic)可提升代码可读性与安全性。
内容的提问来源于stack exchange,提问作者YUNN
相关产品推荐
相关产品推荐

