我有一个 TextEditingController,如果用户点击一个按钮,它填充信息。我似乎不知道如何改变 Textfield或 TextFormField内部的文本。有解决办法吗?
TextEditingController
Textfield
TextFormField
_mytexteditingcontroller.value = new TextEditingController.fromValue(new TextEditingValue(text: "My String")).value;
这似乎工作,如果有人有更好的办法,请随时让我知道。
只需更改 text属性
text
TextField( controller: txt, ), RaisedButton(onPressed: () { txt.text = "My Stringt"; }),
而 txt只是 TextEditingController
txt
var txt = TextEditingController();
您可以使用文本编辑控制器来操作文本字段中的值。
var textController = new TextEditingController();
现在,创建一个新的 textfield,并将 textController设置为 textfield 的控制器,如下所示。
textController
new TextField(controller: textController)
现在,在代码中的任何位置创建一个 RaisedButton,并在 RaisedButton的 onPressed方法中设置所需的文本。
RaisedButton
onPressed
new RaisedButton( onPressed: () { textController.text = "New text"; } ),
截图:
创建一个 TextEditingController:
final TextEditingController _controller = TextEditingController();
把它分配给你的 TextField或 TextFormField:
TextField
TextField(controller: _controller)
使用 光标位置处的按钮更新文本(假设文本字段中已经有文本) :
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), ), );
它正常工作的材料和库比蒂诺文本领域。
声明 TextEditingController。
向 TextField 提供控制器。
用户控制器的 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属性。 如果不编辑选择属性,光标将转到新文本的第一个。
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)); }
在与您无关的情况下,不要更改选择属性
如果您只是想替换文本编辑控制器中的整个文本,那么这里的其他答案可以工作。但是,如果希望以编程方式插入、替换选定内容或删除内容,则需要更多的代码。
制作自己的自定义键盘就是其中一个用例。下面的所有插入和删除都是通过编程完成的:
这里的 _controller是 TextEditingController代表 TextField。
_controller
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, ); }
感谢 这个堆栈溢出的答案的帮助。
有几种不同的情况需要考虑:
以下是实施方案:
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作为成员,则不会出现该问题。听起来很奇怪,但是从无状态到有状态的转换是可行的(这是因为小部件在每个输入上都被重新绘制到文本编辑控制器,而这不保留状态)例如:
StatefulWidget
状态: (工作)
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"), ), ], ); } }