【问题标题】:Flutter how to get cursor in text field to stop moving to the beginning?Flutter如何使文本字段中的光标停止移动到开头?
【发布时间】:2019-11-14 07:10:43
【问题描述】:

我在flutter 应用程序中有一个text field,旨在让用户编辑数据。当 TextField 出现时,其中已经有数据,效果很好。问题在于,当用户将光标放在 TextField 的末尾或其中的任何位置并开始输入时,光标会移回开头,有时会删除第一个或两个单词。

我尝试将函数调用放在 setState 内的控制器中,但没有帮助。如果我根本不使用控制器,问题就会消失,但是在他们点击框外后我无法保存他们的输入。

这是文本字段的代码,它正在更改中

TextField(
    decoration: InputDecoration(
       border: InputBorder.none
    ),
    controller: controller,
    autofocus: true,
    onChanged: (text) {
       controller..text = text;
       controller..selection = TextSelection.collapsed(offset: controller.text.length);
    },
    maxLines: 8,

这里是我创建控制器的地方

 TextEditingController controller = new TextEditingController();
 controller.text = *initial text here*;

这里是颤振医生

[√] Flutter (Channel stable, v1.5.4-hotfix.2, on Microsoft Windows [Version 10.0.17134.829], locale en-US)
    • Flutter version 1.5.4-hotfix.2 at C:\Users\jhall\Desktop\flutter
    • Framework revision 7a4c33425d (9 weeks ago), 2019-04-29 11:05:24 -0700
    • Engine revision 52c7a1e849
    • Dart version 2.3.0 (build 2.3.0-dev.0.5 a1668566e5)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at C:\Users\jhall\AppData\Local\Android\sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-Q, build-tools 28.0.3
    • Java binary at: C:\Program Files\Android\Android Studio1\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
    • All Android licenses accepted.
[√] Android Studio (version 3.4)
    • Android Studio at C:\Program Files\Android\Android Studio1
    • Flutter plugin version 35.3.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
[√] VS Code, 64-bit edition (version 1.24.1)
    • VS Code at C:\Program Files\Microsoft VS Code
    • Flutter extension version 2.21.1
[√] Connected device (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API 28) (emulator)
• No issues found!

所以我基本上只需要您期望从文本输入字段中获得的正常功能,以便用户能够将光标放置在他们想要的任何位置并输入。

我已尝试一起摆脱 on Change 问题,但问题仍然存在。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    您不必这样做

    controller..text = text;

    onChanged 内,因为控制器的文本在您将其连接到 TextField 后会自动更改。

    原因是一旦你将一些文本设置为controller,它re-applies 文本从而将光标移动到前面。

    在你的情况下:

    TextField(
        decoration: InputDecoration(
           border: InputBorder.none
        ),
        controller: controller,
        autofocus: true,
        onChanged: (text) {},
        maxLines: 8,
    )
    

    应该可以解决问题。

    【讨论】:

    • 如果我们需要文本字段的初始值怎么办?我们不能同时使用 initialValue 和 controller
    • 控制器:TextEditingController.fromValue(TextEditingValue( text: initialString ?? "", selection: TextSelection.collapsed(offset: initialString?.length ?? 0), ), ),
    • 哦,我明白了,谢谢
    【解决方案2】:

    您可以在更改文本之前捕获光标位置,然后将光标位置重新应用于新文本:

    onChanged: (text) {
           TextSelection previousSelection = controller.selection;
           controller.text = text;
           controller.selection = previousSelection;
        }
    

    【讨论】:

    • 如果先前的选择大于当前文本的长度可能会导致问题,在这种情况下设置为新的长度选择,例如 TextSelection t = TextSelection(baseOffset: text.length, extentOffset: text.length);
    【解决方案3】:

    我认为,如果您只是从代码中删除 onChange,您将得到您所需要的!

    有一点很重要,也可能会导致问题,那就是您的控制器必须设置一次!你可以把它放在你的 Widget 状态的构造函数中,或者放在initState() 中。会是这样的:

    import 'package:flutter/material.dart';
    
    class MyStatefulPage extends StatefulWidget {
      @override
      State<MyStatefulPage> createState() {
        return _MyStatefulPageState();
      }
    }
    class _MyStatefulPageState extends State<MyStatefulPage> {
    
      TextEditingController controller;
    
      @override
      void initState() {
        super.initState();
        controller = new TextEditingController();
        controller.text = 'My Initial Text';
      } 
    
      @override
      Widget build(BuildContext context) {
        return TextField(
          decoration: InputDecoration(
           border: InputBorder.none
          ),
          controller: controller,
          autofocus: true,
          maxLines: 8,
        );
      }
    }
    

    【讨论】:

    • 我删除了 onChange,它现在可以工作了。
    【解决方案4】:

    使用这个:

    _controller.text = modifytext();
    _controller.selection = TextSelection.fromPosition(TextPosition(offset: _controller.text.length));
    

    【讨论】:

      【解决方案5】:
      TextField(
       enableInteractiveSelection: false
      )
      

      将此设置为 true 将启用诸如长按 TextField 选择文本并显示剪切/复制/粘贴菜单,然后点击 移动文本插入符号。

      如果为 false,则用户无法调整文本选择, 文本无法复制,用户无法粘贴到文本字段中 从剪贴板。

      默认为真。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        • 2017-10-07
        • 1970-01-01
        • 1970-01-01
        • 2020-10-31
        • 2023-02-20
        相关资源
        最近更新 更多