如何更改文本字段颤动中的值?
Posted
技术标签:
【中文标题】如何更改文本字段颤动中的值?【英文标题】:How do you change the value inside of a textfield flutter? 【发布时间】:2018-12-10 03:42:17 【问题描述】:我有一个TextEditingController
,如果用户点击一个按钮,它会填写信息。我似乎不知道如何更改 Textfield
或 TextFormField
中的文本。有解决办法吗?
【问题讨论】:
【参考方案1】:只需更改text
属性
TextField(
controller: txt,
),
RaisedButton(onPressed: ()
txt.text = "My Stringt";
),
而txt
只是TextEditingController
var txt = TextEditingController();
【讨论】:
使用此代码将光标移到字段的左侧。有什么办法解决吗? @rickdroio 查看this answer,它会将光标放在末尾。 @rickdroio 是的,下面的评论***.com/a/58307018/7691350 所以我必须为要数据绑定的每个输入添加一个 TextEditingController?【参考方案2】:只是设置的问题
_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),
),
);
它适用于 Material 和 Cupertino 文本字段。
【讨论】:
这应该是正确的答案,因为它处理了更改控制器值和光标一直回到文本开头的问题 还有一个建议,在提供偏移量的时候,我们可以这样做: int currentOffset = _textEditingController.selection.base.offset;然后提供 currentOffset 作为偏移量。这也将处理用户在字符串之间的情况。【参考方案3】:您可以使用文本编辑控制器来操作文本字段中的值。
var textController = new TextEditingController();
现在,创建一个新的文本字段并将textController
设置为文本字段的控制器,如下所示。
new TextField(controller: textController)
现在,在代码中的任意位置创建一个RaisedButton
,并在RaisedButton
的onPressed
方法中设置所需的文本。
new RaisedButton(
onPressed: ()
textController.text = "New text";
),
【讨论】:
TextField的文本修改不需要调用setState【参考方案4】:截图:
创建TextEditingController
:
final TextEditingController _controller = TextEditingController();
将其分配给您的TextField
或TextFormField
:
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),
);
,
)
【讨论】:
【参考方案5】:_mytexteditingcontroller.value = new TextEditingController.fromValue(new TextEditingValue(text: "My String")).value;
如果有人有更好的方法,这似乎可行,请随时告诉我。
【讨论】:
怎么样:_mytexteditingcontroller.text="你的文字" 如果你想创建一个已经填写了值的 TextField 就完美了:)【参考方案6】:第一件事
TextEditingController MyController= new TextEditingController();
然后将其添加到 init State 或任何 SetState 中
MyController.value = TextEditingValue(text: "ANY TEXT");
【讨论】:
【参考方案7】:如果您只是想替换文本编辑控制器中的整个文本,那么这里的其他答案也可以。但是,如果您想以编程方式插入、替换选择或删除,则需要更多代码。
制作您自己的自定义键盘是其中一个用例。下面的所有插入和删除都是以编程方式完成的:
插入文字
这里的_controller
是TextEditingController
的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,
);
感谢 this Stack Overflow answer 对此的帮助。
删除文字
有几种不同的情况需要考虑:
-
有一个选择(删除选择)
光标在开头(不要做任何事情)
其他(删除前一个字符)
这里是实现:
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,
);
完整代码
你可以在我的文章Custom In-App Keyboard in Flutter中找到完整的代码和更多的解释。
【讨论】:
我正在使用这段代码,它基本上是在 textField 的值不为 null 时在开始时添加值,但问题是当它在光标的输入位置更改并开始在值之前写入时添加 $ 符号时如果之前的值为 1 美元,那么它会写入 2 美元。那么这项任务有什么解决方案或更好的逻辑吗? "onChanged: (value) if (dollarSignAdded == false) priceTextEditingController.value=TextEditingValue( text: "\$" +priceTextEditingController.text); dollarSignAdded = true; else if (value.isEmpty) dollarSignAdded = false;
"【参考方案8】:
如果您使用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"),
),
],
);
【讨论】:
【参考方案9】:这是一个完整示例,其中父小部件控制子小部件。父小部件使用计数器更新子小部件(Text 和 TextField)。
要更新 Text 小部件,您只需传入 String 参数即可。 要更新 TextField 小部件,您需要传入一个控制器,并在控制器中设置文本。
main.dart:
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,),
]),
);
【讨论】:
【参考方案10】:只需更改控制器的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));
在对您无关紧要的情况下,不要更改选择属性
【讨论】:
【参考方案11】:声明 TextEditingController。
为 TextField 提供控制器。
用户控制器的 text 属性来改变 textField 的值。
关注这位官方solution to the problem
【讨论】:
这对之前添加的解决方案有什么好处?以上是关于如何更改文本字段颤动中的值?的主要内容,如果未能解决你的问题,请参考以下文章