我是Riverpod的新手,正在尝试从Provider迁移一个应用程序。如果我有一个TextField
,并且想根据我的提供者模型设置它的值,我会这样做:
class MyWidget extends StatefulWidget{
const MyWidget({ Key? key }) : super(key: key);
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
var controller = TextEditingController();
@override
void didChangeDependencies() {
super.didChangeDependencies();
//Set the value here...
var model = Provider.of<Model>(context);
controller.text = model.name;
}
Widget build(BuildContext context) {
return TextField(controller: controller)
}
}
据我所知,didChangeDependencies()
会监听Provider.of<Model>(context)
的更改,并相应地更新我的控制器。
我正试图用Provider实现同样的事情,但我永远无法显示TextField
的值。
class MyWidget extends ConsumerStatefulWidget {
const MyWidget({Key? key}) : super(key: key);
@override
ConsumerState<ConsumerStatefulWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends ConsumerState<MyWidget> {
var controller = TextEditingController();
@override
void didChangeDependencies() {
super.didChangeDependencies();
//Trying the same thing here...
final name = ref.watch(providerName);
controller.text = name;
}
Widget build(BuildContext context) {
final name = ref.watch(providerName);
return Column(
children: [
//This doesn't work:
TextField(controller: controller),
//I know my provider has the value, because this works fine:
Text(name),
]
}
}
如何更新TextEditingController
的text
属性?
来自Riverpod官方网站
///1.创建一个[StateNotifier]子类,StateNotifier是一个可以定义可以改变状态的函数的东西,就像在这种状态下是String类型的一样,你也可以使用对象(类而不是基元类型(
class Counter extends StateNotifier<String> {
Counter() : super('');
void changeText(String text){
state=text;
}
///2.创建一个提供者[StateNotifierProvider],用它你可以在你的小部件中使用
final counterProvider = StateNotifierProvider<Counter, String>((ref) {
return Counter();
});
///3.消费提供商这就是我们如何用我们的小部件附加状态
class Home extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final text = ref.watch(counterProvider);
return Text('$text');
}
}
所以在这里你可以添加像按钮这样的小部件,onTap执行像这样的代码
onTap()=>changeText(textController.text);
因此,您的文本[text('$text'(;]将自动更改。
最初我第一次尝试时收到了这个错误:在构建错误期间调用了setState((或markNeedsBuild((。
过了一段时间,我找到了一种方法来做你正在寻找的事情,如下所示,它有点不那么直观。
class _DirectorySelectState extends ConsumerState<DirectorySelect> {
final directoryTextFieldController = TextEditingController();
@override
void dispose() {
directoryTextFieldController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
ref.listen(selectedDirectoryProvider, (previous, next) {
setState(() {
SelectedDirectoryState selectedDirs = next;
directoryTextFieldController.value = TextEditingValue(text: selectedDirs.directory);
});
});
return Row(children: [
Text(widget.label),
const SizedBox(
width: 10,
),
Expanded(
child: TextFormField(
controller: directoryTextFieldController,
String inputText = controller.text;