Flutter+GetX自定义TextField光标异常问题求助
问题解决:Flutter GetX TextField光标不跟随输入的问题
问题根源
你当前的写法每次在Obx刷新时都会新建一个TextEditingController,这会导致TextField丢失之前的光标状态——每次输入字符触发Obx重建后,输入框相当于被重新初始化,光标自然回到起始位置。
解决方案
核心思路是让TextEditingController成为GetX控制器的持久化成员,而不是在UI层随组件重建反复创建。
步骤1:改造GetX控制器
在你的searchCargoesController中定义并初始化两个TextEditingController,同时做好双向绑定和资源释放:
class SearchCargoesController extends GetxController { // 保留原有的obs变量用于业务逻辑 final fromWhereController = ''.obs; final toWhereController = ''.obs; // 定义持久化的TextEditingController late final TextEditingController fromTextCtrl; late final TextEditingController toTextCtrl; @override void onInit() { super.onInit(); // 初始化控制器并绑定初始值 fromTextCtrl = TextEditingController(text: fromWhereController.value); toTextCtrl = TextEditingController(text: toWhereController.value); // 添加监听器,同步输入框内容到obs变量 fromTextCtrl.addListener(() { fromWhereController.value = fromTextCtrl.text; }); toTextCtrl.addListener(() { toWhereController.value = toTextCtrl.text; }); } @override void onClose() { // 释放控制器资源,避免内存泄漏 fromTextCtrl.dispose(); toTextCtrl.dispose(); super.onClose(); } // 封装交换逻辑 void swapFromTo() { final tempText = fromTextCtrl.text; fromTextCtrl.text = toTextCtrl.text; toTextCtrl.text = tempText; // 监听器会自动同步到obs变量,无需手动调用update() } }
步骤2:修改UI层代码
移除UI层中每次创建TextEditingController的逻辑,直接使用控制器中定义的持久化实例,同时简化Obx或直接移除(因为TextEditingController自身会触发UI更新):
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( height: Dimensions.height50, width: Dimensions.width130, child: CustomTextField( hintText: "from".tr, textEditingController: searchCargoesController.fromTextCtrl, textInputType: TextInputType.streetAddress, // 无需onChanged,监听器已同步内容到obs变量 ), ), InkWell( onTap: () => searchCargoesController.swapFromTo(), child: SizedBox( width: Dimensions.width20, child: SvgPicture.asset("assets/icons/from_to1.svg"), ), ), SizedBox( height: Dimensions.height50, width: Dimensions.width130, child: CustomTextField( hintText: "to".tr, textEditingController: searchCargoesController.toTextCtrl, textInputType: TextInputType.streetAddress, ), ), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(Dimensions.radius10), gradient: const LinearGradient( colors: [Colors.amber, Colors.yellow], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), child: IconButton( onPressed: () {}, icon: Icon( Icons.search_outlined, color: Colors.white, size: Dimensions.icon20, ), ), ), ], )
效果说明
- 输入时光标会正常跟随输入位置,因为
TextEditingController是持久化的,不会随UI重建而重置状态。 - 点击交换图标时,两个输入框的内容会直接交换,且监听器自动同步到
obs变量,确保业务逻辑中的值正确更新。 - 无需依赖
Obx也能实现UI更新(TextEditingController自身会通知TextField刷新),如果需要监听obs变量做其他业务,可以保留Obx包裹。
内容的提问来源于stack exchange,提问作者Sunnat Amirov
相关产品推荐
相关产品推荐

