我有一个 flutter 应用程序,我想使用 flutter_riverpod 作为全局状态管理器。问题是即使我使用 read 方法,我也无法访问我的变量。我做错了什么?
我的屏幕代码:
class MySCcreenScreen extends ConsumerStatefulWidget {
const MySCcreenScreen({super.key});
@override
ConsumerState<MySCcreenScreen> createState() =>
_MySCcreenScreenState();
}
class _MySCcreenScreenState
extends ConsumerState<MySCcreenScreen>
with AutomaticKeepAliveClientMixin {
bool disabled = true;
@override
Widget build(BuildContext context) {
super.build(context);
final form = ref.watch(complimentFormProvider);
safePrint(form);
void handleProceed() {
safePrint('form.id ${form.id}');
}
double baseScreenPadding = 20;
double screenHeight = getScreenHeight(context);
return Scaffold(
padding: EdgeInsets.symmetric(horizontal: baseScreenPadding),
considerScroll: true,
body:
ConstrainedBox(
constraints: BoxConstraints(
minHeight: screenHeight,
),
child: Column(
children: [
MyInput(
handleSubmit: handleProceed,
),
const SizedBox(height: 20),
SubmitButton(
text: 'Submit',
disabled: disabled,
onPress: handleProceed,
),
],
))
);
}
@override
bool get wantKeepAlive => true;
}
我的输入代码
class MyInput extends ConsumerWidget {
final Function() handleSubmit;
const MyInput({super.key, required this.handleSubmit});
@override
Widget build(BuildContext context, WidgetRef ref) {
final form = ref.watch(formProvider);
void setId(String newValue) {
safePrint('newValue $newValue');
safePrint('form.id ${form.id}');
ref
.read(formProvider.notifier)
.setId(newValue);
}
return Column(
children: [
const SizedBox(height: 20),
InputId(
setId: setId,
onSubmit: handleSubmit,
keyboardAction: TextInputAction.next,
),
],
);
}
}
我的InputId代码:
void emptyFunction() {}
class InputId extends StatefulWidget {
final ValueChanged<String> setId;
final TextInputAction keyboardAction;
final Function() onSubmit;
const InputId({
super.key,
required this.setId,
this.keyboardAction = TextInputAction.done,
this.onSubmit = emptyFunction,
});
@override
State<InputId> createState() => _InputIdState();
}
class _InputIdState extends State<InputId> {
final TextEditingController inputController = TextEditingController();
@override
void dispose() {
inputController.dispose();
super.dispose();
}
void updateId() {
widget.setId(inputController.text);
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
textInputAction: widget.keyboardAction,
onEditingComplete: widget.onSubmit,
controller: inputController,
enableSuggestions: false,
autocorrect: false,
keyboardType: TextInputType.number,
enableInteractiveSelection: false,
autofocus: true,
onChanged: (value) {
updateId();
},
),
],
);
}
}
还有我的 Riverpod 代码:
class MyFormState {
String id;
String name;
MyFormState(
{this.id = '', this.name = ''});
}
class MyFormNotifier extends StateNotifier<MyFormState> {
MyFormState _state = MyFormState();
MyFormNotifier() : super(MyFormState());
void setId(String id) {
_state = MyFormState(
id: id,
name: _state.name,
);
}
void setName(String name) {
_state = MyFormState(
id: _state.id,
name: name,
);
}
}
final formProvider =
StateNotifierProvider<MyFormNotifier, MyFormState>(
(ref) => MyFormNotifier(),
);
需要注意的是,我对树小部件持怀疑态度: 屏幕 - -输入 ------输入Id 这有影响吗?
StateNotifier 拥有一个状态变量,而我使用的是私有 _state 变量。 所以我的改变应该是这样的:
class MyFormNotifier extends StateNotifier<MyFormState> {
MyFormNotifier() : super(MyFormState());
void setId(String id) {
state = MyFormState(
id: id,
name: state.name, // Aqui estamos usando o estado atual
);
}
void setName(String name) {
state = MyFormState(
id: state.id,
name: name,
);
}
}