我是 flutter 和 Riverpod 的新手,我正在尝试使用提供程序实现一些基本表单数据绑定。
我有一个代表正在填写的表单的模型,并且我有一个通知程序提供程序设置来向消费者提供该模型。但是,当值更改时,我无法重建复选框小部件,因此它实际上从未显示为选中状态。即使表单数据中的基础值是正确的。
这是我正在使用的代码:
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class MyFormData {
String name;
bool isSelected;
MyFormData(
this.name,
this.isSelected
);
}
class MyFormController extends Notifier<MyFormData>{
@override
MyFormData build() {
return MyFormData("test", false);
}
bool get isSelected => state.isSelected;
set isSelected(value) {
state.isSelected = value;
state = state;
}
}
final myFormControllerProvider = NotifierProvider<MyFormController, MyFormData>(MyFormController.new);
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Home(),
);
}
}
class Home extends ConsumerWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final formData = ref.watch(myFormControllerProvider);
return Scaffold(
appBar: AppBar(title: const Text("My Form")),
body: Center(
child: Card(
child:Row(
children: [
Checkbox(
value: formData.isSelected,
onChanged: (value) => ref.read(myFormControllerProvider.notifier).isSelected = value!),
const Text('I am a Checkbox')
],
)
)
)
);
}
}
我觉得这遵循我找到的每个复选框绑定的“示例教程”,但我知道我错过了一些东西。谁能帮助确定我做错了什么?
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
part 'this_file_name.freezed.dart';
part 'this_file_name.g.dart';
@freezed
class MyFormData extends Equatable with _$MyFormData {
const MyFormData._();
const factory MyFormData({
required String name,
required bool isSelected,
}) = _MyFormData;
@override
List<Object?> get props => [name, isSelected];
}
@riverpod
class MyFormController extends _$MyFormController {
@override
MyFormData build() => MyFormData("test", false);
bool get isSelected => state.isSelected;
set isSelected(value) {
state = state.copyWith(isSelected: value);
}
}
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => const MaterialApp(
home: Home(),
);
}
class Home extends ConsumerWidget {
const Home({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final formData = ref.watch(myFormControllerProvider.select(data => data.isSelected));
// prevent unwanted updates: if this widget should updated only if the user change the isSelected field, then this will help (i.e. if you change the name this widget will not repainted).
return Scaffold(
appBar: AppBar(title: const Text("My Form")),
body: Center(
child: Card(
child:Row(
children: [
Checkbox(
value: formData.isSelected,
onChanged: (value) => ref.read(myFormControllerProvider.notifier).isSelected = value!),
const Text('I am a Checkbox')
],
)
)
)
);
} }
应该可以! 试试这个(我没有尝试过......但应该可行)。 不要忘记添加到您的 pubspec.yaml :
dependencies:
equatable: ^2.0.5
riverpod_annotation: ^2.3.5
dev_dependencies:
build_runner: ^2.4.8
riverpod_generator: ^2.4.0