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

Flutter TextField光标问题求助:输入时光标被挤至右侧隐藏

实现Flutter TextField的计算器式光标排版逻辑

要实现类似计算器的文本排版与光标行为,核心是让文本溢出时自动向左滚动,确保光标始终保持在可视区域的最右端,不会被挤到视野外。以下是具体实现方案:

核心思路

  1. 文本右对齐:设置TextField的文本对齐方式为右对齐,匹配计算器的排版习惯。
  2. 滚动控制:通过ScrollController监听文本变化,动态调整滚动位置,确保光标始终处于可视区域的右侧。
  3. 文本变更监听:利用TextEditingController监听输入内容的变化,在每次文本更新后调整滚动偏移。

完整代码示例

import 'package:flutter/material.dart';

class CalculatorTextField extends StatefulWidget {
  const CalculatorTextField({super.key});

  @override
  State<CalculatorTextField> createState() => _CalculatorTextFieldState();
}

class _CalculatorTextFieldState extends State<CalculatorTextField> {
  final TextEditingController _textController = TextEditingController();
  final ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    // 监听文本变化,实时调整滚动位置
    _textController.addListener(_adjustScrollToKeepCursorVisible);
  }

  void _adjustScrollToKeepCursorVisible() {
    // 等待布局完成后再调整滚动,避免获取无效的滚动参数
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (_scrollController.hasClients) {
        // 滚动到最大偏移量,让光标始终停在可视区域最右端
        _scrollController.jumpTo(_scrollController.position.maxScrollExtent);
      }
    });
  }

  @override
  void dispose() {
    _textController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _textController,
      scrollController: _scrollController,
      textAlign: TextAlign.right,
      style: const TextStyle(fontSize: 28, fontWeight: FontWeight.w500),
      decoration: const InputDecoration(
        border: OutlineInputBorder(
          borderRadius: BorderRadius.all(Radius.circular(8)),
        ),
        contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
        hintText: "输入计算式",
      ),
    );
  }
}

// 调用示例
void main() {
  runApp(const MaterialApp(
    home: Scaffold(
      body: Center(
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: 24),
          child: CalculatorTextField(),
        ),
      ),
    ),
  ));
}

效果说明

  • 当输入文本未超出TextField宽度时,光标正常跟随输入位置。
  • 当文本溢出后,继续输入(包括点击中间位置输入),文本会自动向左滚动,光标始终保持在可视区域的最右端,不会被隐藏。
  • 如果需要强制光标始终停在文本末尾(类似纯追加式的计算器),可以添加onTap回调,将光标位置强制设置到文本末尾:
onTap: () {
  WidgetsBinding.instance.addPostFrameCallback((_) {
    _textController.selection = TextSelection.fromPosition(
      TextPosition(offset: _textController.text.length),
    );
    _adjustScrollToKeepCursorVisible();
  });
},

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:57:38