我在使用Flutter编写Android程序的时候发现,在个别设备上压后台,然后等待1分半钟左右再回来会出现卡死的情况。
我当时是使用 OverlayEntry
代码如下:
import 'dart:async';
import 'package:flutter/material.dart';
class CustomOverlayEntry extends StatefulWidget {
final VoidCallback closeOverlayEntry;
final VoidCallback? updateIconState;
final Widget child;
final double? top;
final double? bottom;
final double? left;
final double? right;
final double width;
final double height;
const CustomOverlayEntry({
super.key,
required this.closeOverlayEntry,
required this.child,
required this.width,
required this.height,
this.top,
this.bottom,
this.left,
this.right,
this.updateIconState,
});
@override
State<CustomOverlayEntry> createState() => _CustomOverlayEntryState();
}
class _CustomOverlayEntryState extends State<CustomOverlayEntry> with WidgetsBindingObserver {
bool isShow = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
print('didChangeAppLifecycleState state : $state');
if (state == AppLifecycleState.paused) {
setState(() {
isShow = false;
});
await Future.delayed(const Duration(milliseconds: 200));
if (mounted) {
widget.closeOverlayEntry();
widget.updateIconState?.call();
}
}
}
Future<void> _handleBackgroundTap() async {
if (!mounted || !isAppResumed || !isShow) return;
setState(() {
isShow = false;
});
await Future.delayed(const Duration(milliseconds: 200));
if (mounted) {
widget.closeOverlayEntry();
widget.updateIconState?.call();
}
}
@override
Widget build(BuildContext context) {
return MediaQuery.removePadding(
context: context,
removeTop: true,
removeBottom: true,
child: Scaffold(
backgroundColor: Colors.transparent,
body: Stack(
children: [
Positioned.fill(
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: _handleBackgroundTap,
child: Container(color: Colors.transparent),
),
),
Positioned(
top: widget.top,
bottom: widget.bottom,
left: widget.left,
right: widget.right,
child: AnimatedOpacity(
opacity: isShow ? 1.0 : 0.0,
duration: const Duration(milliseconds: 100),
child: Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
padding: const EdgeInsets.symmetric(vertical: 10),
child: widget.child,
),
),
],
),
),
);
}
}
我选择的方式是在压后台之后直接关闭悬浮窗。