输入时光标默认为文本字段的开头,使用 TextEditingController + onChanged - Flutter

Posted

技术标签:

【中文标题】输入时光标默认为文本字段的开头,使用 TextEditingController + onChanged - Flutter【英文标题】:Cursor defaults to start of Textfield when typing, using TextEditingController + onChanged - Flutter 【发布时间】:2020-10-31 23:33:18 【问题描述】:

我正在开发一个应用程序,该应用程序将有一些单行文本字段,这些文本字段基本上用于在每个文本字段中存储注释,因此我使用 shared_preferences 依赖项来设置/获取这些值,但是我发现它与 TextEditingController 和 onChanged 参数一起使用键入时光标移动到文本字段的开头。

我对此进行了研究,可以看到很多建议使用侦听器(如下所示)为 TextSelection 将光标永久设置在文本字段的末尾,但我希望允许用户将光标移动到任何地方在该框中输入他们喜欢的位置。

text1.addListener(() 
      final text = text1.text;
      text1.value = text1.value.copyWith(
        text: text,
        selection:
            TextSelection(baseOffset: text.length, extentOffset: text.length),
        composing: TextRange.empty,
      );
    );

下面是一个复制我遇到的问题的示例,如果有人有任何建议吗? 我可以使用保存按钮,但我希​​望只允许用户修改文本并将光标移动到他们需要的位置,然后 onChanged 参数可以保存对 shared_preferences 的任何更改;

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Textfield Test'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 
  
  TextEditingController text1 = TextEditingController();
  SharedPreferences sharedPreferences;

  @override
  void initState() 
    super.initState();
    getText();
  
 

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
                controller: text1,
                onChanged: _setText,
              ),
          ],
        ),
      ),
    );
  

  _setText(String value) async 
    sharedPreferences = await SharedPreferences.getInstance();
    setState(() 
      sharedPreferences.setString("text1", text1.text);
      getText();
    );
  

  getText() async 
    sharedPreferences = await SharedPreferences.getInstance();
    setState(() 
        text1.text = sharedPreferences.getString("text1");
    );
  


【问题讨论】:

【参考方案1】:

你必须等待这个函数的输出,因为这是异步函数。

onChanged: (value)async
    _setText(value)

【讨论】:

我认为你必须在调用函数之前添加等待 我试过 _setText(value);并等待 _setText(value);但两者似乎仍然存在相同的问题 最好使用共享首选项的静态类,这样您就无需等待共享首选项对象的初始化。【参考方案2】:

只是为了让任何人知道阅读这篇文章,我发现我哪里出错了。

在定义的_setText函数id上,我只需要删除'getText();'行,现在它在输入时不会移动光标,并且工作正常。

【讨论】:

以上是关于输入时光标默认为文本字段的开头,使用 TextEditingController + onChanged - Flutter的主要内容,如果未能解决你的问题,请参考以下文章

在Vue中输入文本字段时光标跳出

更新其中的 html 时光标跳转到代码标记的开头

input移动光标至开头

删除 Chrome 自动完成的输入光标颜色?

在Pycharm中写python代码时光标变粗

coreldraw 12 里打字时光标看不到怎么办?