[英]Check if Stateless widget is disposed in flutter
當我的無狀態小部件構建時,我使用以下代碼按順序播放一些聲音:
await _audioPlayer.play(contentPath1, isLocal: true);
await Future.delayed(Duration(seconds: 4));
await _audioPlayer.play(contentPath2, isLocal: true);
await Future.delayed(Duration(seconds: 4));
await _audioPlayer.play(contentPath3, isLocal: true);
當用戶在完成播放聲音之前關閉當前小部件時,即使在使用以下代碼關閉當前路由后聲音仍然有效:
Navigator.pop(context);
我的解決方法是使用布爾變量來指示關閉操作是否已完成。
播放聲音代碼:
await _audioPlayer.play(contentPath1, isLocal: true);
if (closed) return;
await Future.delayed(Duration(seconds: 4));
if (closed) return;
await _audioPlayer.play(contentPath2, isLocal: true);
if (closed) return;
await Future.delayed(Duration(seconds: 4));
if (closed) return;
await _audioPlayer.play(contentPath3, isLocal: true);
關閉當前小部件:
closed = true;
_audioPlayer.stop();
如果我的小部件關閉,是否有更好的方法來停止異步方法?
如果您將小部件更改為 StatefulWidget,那么您可以擁有如下功能:
void _playSounds() {
await _audioPlayer.play(contentPath1, isLocal: true);
await Future.delayed(Duration(seconds: 4));
if (!mounted) return;
await _audioPlayer.play(contentPath2, isLocal: true);
await Future.delayed(Duration(seconds: 4));
if (!mounted) return;
await _audioPlayer.play(contentPath3, isLocal: true);
}
然后在 dispose 方法中處理播放器:
@override
void dispose() {
_audioPlayer?.dispose();
super.dispose();
}
mounted
getter 目前已合並到 master 頻道中,但在穩定頻道中仍不可用。
https://github.com/flutter/flutter/pull/111619
同時,我們有 2 個選項
mounted
的 getter。import 'package:flutter/material.dart';
class PrimitiveWrapper<T> {
T value;
PrimitiveWrapper(this.value);
}
class MountedWrapper extends StatefulWidget {
final Widget Function(BuildContext context, PrimitiveWrapper<bool> mounted) builder;
const MountedWrapper({
required this.builder,
super.key,
});
@override
State<MountedWrapper> createState() => _MountedWrapperState();
}
class _MountedWrapperState extends State<MountedWrapper> {
@override
Widget build(BuildContext context) {
return widget.builder.call(context, PrimitiveWrapper(mounted));
}
}
class SubmitBtn extends StatelessWidget {
...
Future<void> onSubmit(WidgetRef ref, BuildContext context, PrimitiveWrapper<bool> mounted) async {
...
await topicRepo.add(topic);
if (!mounted.value) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Created topic'),
),
);
}
@override
Widget build(BuildContext context) {
return MountedWrapper(
builder: (context, mounted) {
return Consumer(
builder: (context, ref, child) {
return ElevatedButton(
onPressed: () {
onSubmit(ref, context, mounted);
},
child: const Text('Create'),
);
},
);
},
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.