Flutter中点击单选按钮如何动态修改TextField的label值
问题根因
你代码中调用的setState是单选按钮组件自身的状态更新方法,只会触发单选按钮组件重绘,不会触发同级的输入框组件重绘,因此即使全局存储的label变量值发生了变化,输入框没有触发重新构建就不会同步更新显示。
解决方法
将跨组件共享的状态放到共同的父组件DebugPage中管理,通过回调和参数传递的方式实现状态同步,改造后的完整代码如下:
import 'package:flutter/material.dart'; class DebugPage extends StatefulWidget { @override _DebugPage createState() => _DebugPage(); } class _DebugPage extends State<DebugPage> { // 共享状态统一放到父组件管理 List<bool> btn_radio = [true, false]; String? label = '初始Label'; // 可自定义初始值 final TextEditingController _controller_Name = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( // 这里替换为你自己的customSubAppBar实现即可 appBar: AppBar(title: Text("Debug")), body: Center( child: Column( mainAxisSize: MainAxisSize.max, children: [ Container(height: MediaQuery.of(context).size.height * 0.3), // 给单选组件传状态和变更回调 BuildAppRadioButton( btnRadio: btn_radio, onRadioChanged: (int selectIndex) { setState(() { btn_radio = [selectIndex == 0, selectIndex == 1]; // 选中不同选项修改对应label label = selectIndex == 0 ? 'Private专属标签' : 'Company企业标签'; }); }, ), // 给输入框传当前label值 BuildAppFieldName( label: label, controller: _controller_Name, ), ], ), )); } } // 单选按钮改造为接收父组件参数 class BuildAppRadioButton extends StatelessWidget { final List<bool> btnRadio; final Function(int selectIndex) onRadioChanged; const BuildAppRadioButton( {super.key, required this.btnRadio, required this.onRadioChanged}); @override Widget build(BuildContext context) { return Row( children: [ Spacer(), Container( width: MediaQuery.of(context).size.width * 0.37, child: CustomRadioButtonRegister( isPressed: btnRadio[0], label: 'Private', padding: const EdgeInsets.symmetric(horizontal: 5.0), value: true, groupValue: btnRadio[0], onChanged: (bool newValue) { onRadioChanged(0); }, ), ), Spacer(), Container( width: MediaQuery.of(context).size.width * 0.37, child: CustomRadioButtonRegister( isPressed: btnRadio[1], label: "Company", padding: const EdgeInsets.symmetric(horizontal: 5.0), value: true, groupValue: btnRadio[1], onChanged: (bool newValue) { onRadioChanged(1); }, ), ), Spacer(), ], ); } } // 输入框改造为接收父组件传的label class BuildAppFieldName extends StatelessWidget { final String? label; final TextEditingController controller; const BuildAppFieldName( {super.key, required this.label, required this.controller}); @override Widget build(BuildContext context) { return Container( width: MediaQuery.of(context).size.width * 0.8, height: MediaQuery.of(context).size.height * 0.09, child: TextFormField( controller: controller, style: TextStyle( color: Colors.black, ), decoration: InputDecoration( labelText: label, labelStyle: TextStyle( color: Colors.black, ), enabledBorder: UnderlineInputBorder( borderSide: BorderSide( color: Colors.black, ), ), ), onChanged: (value) {}, ), ); } } // 保留你原有CustomRadioButtonRegister的实现即可 class CustomRadioButtonRegister extends StatelessWidget { final bool isPressed; final String label; final EdgeInsets padding; final bool value; final bool groupValue; final Function(bool newValue) onChanged; const CustomRadioButtonRegister( {super.key, required this.isPressed, required this.label, required this.padding, required this.value, required this.groupValue, required this.onChanged}); @override Widget build(BuildContext context) { return InkWell( onTap: () => onChanged(!groupValue), child: Container( padding: padding, color: isPressed ? Colors.blue : Colors.grey, child: Text(label, style: TextStyle(color: Colors.white)), ), ); } }
改造后所有共享状态都由父组件DebugPage统一管理,单选按钮选中时通过回调通知父组件更新状态,父组件调用setState会触发所有子组件重绘,输入框拿到新的label参数就会同步更新显示。
内容的提问来源于stack exchange,提问作者user16754196
相关产品推荐
相关产品推荐

