我有一个名为TestMain的flutter屏幕,它有一个支架和白色背景。支架主体应该在某些事件发生时发生变化。事件存储为布尔值。有“isLocked”和“isPaused”,它们由Riverpod流提供程序发出,还有“isCheating”,当Applifecyle事件被触发时发生变化。所有三个布尔值都存储为Riverpod状态提供程序。因为它的全球可访问性。
这是我的“isCheatingProvider”:final isCheatingProvider = StateProvider.autoDispose<bool>((ref) => false);
“isPausedProvider”和“isLockedProvider”相同。
这是测试主屏幕
class TestMain extends ConsumerStatefulWidget {
const TestMain({super.key});
@override
ConsumerState<TestMain> createState() => _TestMainScreenState();
}
class _TestMainScreenState extends ConsumerState<TestMain>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
final isCheating = ref.watch(isCheatingProvider.notifier);
switch (state) {
case AppLifecycleState.resumed:
case AppLifecycleState.inactive:
await sendCheatingAttempt(ref);
setState(() {
isCheating.state = true;
});
break;
case AppLifecycleState.paused:
await sendCheatingAttempt(ref);
setState(() {
isCheating.state = true;
});
break;
case AppLifecycleState.detached:
await sendCheatingAttempt(ref);
setState(() {
isCheating.state = true;
});
break;
}
}
@override
Widget build(BuildContext context) {
final List<Item> items = ref.watch(itemsProvider);
final AsyncValue<dynamic> wsTestListenerMessage =
ref.watch(testListenerProvider);
final isLocked = ref.watch(isLockedProvider.notifier);
final isPaused = ref.watch(isPausedProvider.notifier);
final isCheating = ref.watch(isCheatingProvider.notifier);
wsTestListenerMessage.when(
loading: () => {},
error: (err, stack) => print('Test State Error: $err'),
data: (message) async {
Future.delayed(const Duration(seconds: 0), () {
if (message["lock"] == true) {
isLocked.state = true;
}
if (message["unlock"] == true) {
isLocked.state = false;
}
if (message["paused"] == true) {
isPaused.state = true;
}
if (message["resumed"] == true) {
isPaused.state = false;
}
});
},
);
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: isPaused.state
? const ErrorOverlay(text: 'paused')
: isLocked.state || isCheating.state
? const ErrorOverlay(text: 'cheating')
: const TestView()),
);
}
}
但是它不起作用。不管我怎么做。我在if语句周围添加了Future.delayed(const Duration(seconds: 0), () {}
,因为它抱怨在build方法中更改了提供者。我在didChangeAppLifecycleState()
中使用了setState(),但是不能在侦听器中使用它,因为侦听器会被一遍又一遍地调用。它不应该超过一次地开放。
(ErrorOverlay是一个自定义小部件,只在中间用红色大字母显示文本)
2条答案
按热度按时间vxf3dgd41#
setState
,这将不执行任何操作ref.read(provider.notifier).state
设置状态ref.watch(isCheatingProvider)
通过改变所有这一切是好的测试在我身边:
slsn1g292#
您使用
StateProvider
的方式不正确。若要观看StateNotifier
,您应该使用以及更改提供程序使用
因此,您必须更改所有与提供程序相关的代码。