如何更改文本字段颤动的内部值?

我有一个 TextEditingController,如果用户点击一个按钮,它填充信息。我似乎不知道如何改变 TextfieldTextFormField内部的文本。有解决办法吗?

225708 次浏览
_mytexteditingcontroller.value = new TextEditingController.fromValue(new TextEditingValue(text: "My String")).value;

这似乎工作,如果有人有更好的办法,请随时让我知道。

只需更改 text属性

    TextField(
controller: txt,
),
RaisedButton(onPressed: () {
txt.text = "My Stringt";
}),

txt只是 TextEditingController

  var txt = TextEditingController();

您可以使用文本编辑控制器来操作文本字段中的值。

var textController = new TextEditingController();

现在,创建一个新的 textfield,并将 textController设置为 textfield 的控制器,如下所示。

 new TextField(controller: textController)

现在,在代码中的任何位置创建一个 RaisedButton,并在 RaisedButtononPressed方法中设置所需的文本。

new RaisedButton(
onPressed: () {
textController.text = "New text";
}
),

截图:

enter image description here

  1. 创建一个 TextEditingController:

    final TextEditingController _controller = TextEditingController();
    
  2. 把它分配给你的 TextFieldTextFormField:

    TextField(controller: _controller)
    
  3. 使用 光标位置处的按钮更新文本(假设文本字段中已经有文本) :

    ElevatedButton(
    onPressed: () {
    const newText = 'Hello World';
    final updatedText = _controller.text + newText;
    _controller.value = _controller.value.copyWith(
    text: updatedText,
    selection: TextSelection.collapsed(offset: updatedText.length),
    );
    },
    )
    

第一件事

  TextEditingController MyController= new TextEditingController();

然后将其添加到 init State 或任何 SetState 中

    MyController.value = TextEditingValue(text: "ANY TEXT");

刚刚设置的问题

_controller.text = "New value";

是光标将被重新定位到开始位置(在材料的 TextField 中)。使用

_controller.text = "Hello";
_controller.selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length),
);
setState(() {});

是无效的,因为它重新构建部件的次数超过了必要的次数(在设置 text 属性和调用 setState 时)。

--

我认为最好的方法就是把所有的东西组合成一个简单的命令:

final _newValue = "New value";
_controller.value = TextEditingValue(
text: _newValue,
selection: TextSelection.fromPosition(
TextPosition(offset: _newValue.length),
),
);

它正常工作的材料和库比蒂诺文本领域。

  1. 声明 TextEditingController。

  2. 向 TextField 提供控制器。

  3. 用户控制器的 text 属性更改 textField 的值。

跟着这个官方 解决问题的办法

下面是一个 满了示例,其中父部件控制子部件。父小部件使用计数器更新子小部件(短信文本字段)。

要更新 短信小部件,只需传递 绳子参数即可。 要更新 文本字段小部件,需要传入一个控制器,并在控制器中设置文本。

飞镖:

import 'package:flutter/material.dart';


void main() => runApp(MyApp());


class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
home: Home(),
);
}
}


class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Update Text and TextField demo'),
),
body: ParentWidget());
}
}


class ParentWidget extends StatefulWidget {
@override
_ParentWidgetState createState() => _ParentWidgetState();
}


class _ParentWidgetState extends State<ParentWidget> {
int _counter = 0;
String _text = 'no taps yet';
var _controller = TextEditingController(text: 'initial value');


void _handleTap() {
setState(() {
_counter = _counter + 1;
_text = 'number of taps: ' + _counter.toString();
_controller.text  = 'number of taps: ' + _counter.toString();
});
}


@override
Widget build(BuildContext context) {
return Container(
child: Column(children: <Widget>[
RaisedButton(
onPressed: _handleTap,
child: const Text('Tap me', style: TextStyle(fontSize: 20)),
),
Text('$_text'),
TextField(controller: _controller,),
]),
);
}
}

只需改变控制器的 text or value属性。 如果不编辑选择属性,光标将转到新文本的第一个。

onPress: () {
_controller.value=TextEditingValue(text: "sample text",selection: TextSelection.fromPosition(TextPosition(offset: sellPriceController.text.length)));
}

或者在更改. text 属性时:

 onPress: () {
_controller.text="sample text";
_controller.selection = TextSelection.fromPosition(TextPosition(offset:_controller.text.length));
}

在与您无关的情况下,不要更改选择属性

如果您只是想替换文本编辑控制器中的整个文本,那么这里的其他答案可以工作。但是,如果希望以编程方式插入、替换选定内容或删除内容,则需要更多的代码。

制作自己的自定义键盘就是其中一个用例。下面的所有插入和删除都是通过编程完成的:

enter image description here

插入文本

这里的 _controllerTextEditingController代表 TextField

void _insertText(String myText) {
final text = _controller.text;
final textSelection = _controller.selection;
final newText = text.replaceRange(
textSelection.start,
textSelection.end,
myText,
);
final myTextLength = myText.length;
_controller.text = newText;
_controller.selection = textSelection.copyWith(
baseOffset: textSelection.start + myTextLength,
extentOffset: textSelection.start + myTextLength,
);
}

感谢 这个堆栈溢出的答案的帮助。

删除短信

有几种不同的情况需要考虑:

  1. 有一个选择(删除选择)
  2. 光标在开始(不要做任何事情)
  3. 其他内容(删除前一个字符)

以下是实施方案:

void _backspace() {
final text = _controller.text;
final textSelection = _controller.selection;
final selectionLength = textSelection.end - textSelection.start;


// There is a selection.
if (selectionLength > 0) {
final newText = text.replaceRange(
textSelection.start,
textSelection.end,
'',
);
_controller.text = newText;
_controller.selection = textSelection.copyWith(
baseOffset: textSelection.start,
extentOffset: textSelection.start,
);
return;
}


// The cursor is at the beginning.
if (textSelection.start == 0) {
return;
}


// Delete the previous character
final newStart = textSelection.start - 1;
final newEnd = textSelection.start;
final newText = text.replaceRange(
newStart,
newEnd,
'',
);
_controller.text = newText;
_controller.selection = textSelection.copyWith(
baseOffset: newStart,
extentOffset: newStart,
);
}

全密码

您可以在我的文章 Flutter 的自定义应用程序内键盘中找到完整的代码和更多的解释。

如果使用 StatefulWidget_controller作为成员,则不会出现该问题。听起来很奇怪,但是从无状态到有状态的转换是可行的(这是因为小部件在每个输入上都被重新绘制到文本编辑控制器,而这不保留状态)例如:

状态: (工作)

class MyWidget extends StatefulWidget {
const MyWidget(
{Key? key})
: super(key: key);


@override
_MyWidgetState createState() =>
_MyWidgetState();
}


class _MyWidgetState
extends State<MyWidget> {
late TextEditingController _controller;


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


_controller = TextEditingController(text: "My Text");
}


@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
controller: _controller,
),
],
);
}
}

无国籍: (问题)

class MyWidget extends StatelessWidget {
const MyWidget(
{Key? key})
: super(key: key);


@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
controller: TextEditingController(text: "My Text"),
),
],
);
}
}