我正在尝试使用 Riverpod
状态管理。我有两个 TextFormField
,我想通过使用 Text
取每个字段中输入的值的总和来设置 StateNotifierProvider
的值。
在以下代码中,CashCounterData
是由 StateNotifier
、CashCounter
使用的数据模型。通知程序有两个方法,setCount
和 setCash
,它们在每个 onChanged
的 TextFormField
方法中调用。
final cashProvider = StateNotifierProvider<CashCounter, CashCounterData>((ref) => CashCounter());
class CashCounter extends StateNotifier<CashCounterData> {
CashCounter() : super(_initialData);
static const _initialData = CashCounterData(0, 0);
void setCount(int value){
state = CashCounterData(value, state.cash);
}
void setCash(value){
state = CashCounterData(state.count, value);
}
int get count => state.count;
int get cash => state.cash;
}
class CashCounterData {
final int count;
final int cash;
const CashCounterData(this.count, this.cash);
}
接下来,我实现了用户界面,并尝试结合上面定义的 StateNotifierProvider
。但是,当我在每个 TextFormField
中输入值时,Text
小部件始终显示 0
。
class CalculatableTextFormField extends HookWidget {
@override
Widget build(BuildContext context) {
final cashCounterProvider = useProvider(cashProvider.notifier);
final TextEditingController _count = TextEditingController();
final TextEditingController _cash = TextEditingController();
return Scaffold(
body: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${cashCounterProvider.count + cashCounterProvider.cash}'
),
TextFormField(
controller: _count,
keyboardType: TextInputType.number,
onChanged: (value)=>cashCounterProvider.setCount(int.parse(value)),
),
TextFormField(
controller: _cash,
keyboardType: TextInputType.number,
onChanged: (value)=>cashCounterProvider.setCash(int.parse(value)),
)
],
),
),
);
}
}
我缺少什么才能获得所需的行为?
答案 0 :(得分:1)
您正在查看通知程序,而不是状态。状态会发生变化,因此会通知侦听器。
如果你只是改变它应该可以工作:
final cashCounterProvider = useProvider(cashProvider.notifier);
到:
final cashCounterProvider = useProvider(cashProvider);
然后,在您的更改处理程序中:
onChanged: (value) => context.read(cashProvider.notifier).setCash(int.tryParse(value) ?? 0),
在这样的处理程序中使用提供程序时,更喜欢上面演示的 context.read
而非 avoid unnecessary rebuilds。
如果您将 TextEditingControllers 放在 build 方法中,您还需要使用钩子。
final TextEditingController _count = useTextEditingController();
final TextEditingController _cash = useTextEditingController();
总的来说,您的解决方案如下:
class CalculatableTextFormField extends HookWidget {
@override
Widget build(BuildContext context) {
final cashCounterProvider = useProvider(cashProvider);
final TextEditingController _count = useTextEditingController();
final TextEditingController _cash = useTextEditingController();
return Scaffold(
body: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('${cashCounterProvider.count + cashCounterProvider.cash}'),
TextFormField(
controller: _count,
keyboardType: TextInputType.number,
onChanged: (value) =>
context.read(cashProvider.notifier).setCount(int.tryParse(value) ?? 0),
),
TextFormField(
controller: _cash,
keyboardType: TextInputType.number,
onChanged: (value) =>
context.read(cashProvider.notifier).setCash(int.tryParse(value) ?? 0),
)
],
),
),
);
}
}