当flutter设置全屏模式时
SystemChrome.setEnabledSystemUIOverlays([]);
在widget中获取的padding是0
MediaQuery.of(context).padding
非全屏模式可以正常获取到值。
如果是全屏模式时,那么SafeArea就失效了。
废话不多说,下面给出我的解决方案:
main(){
//这里能获取到padding
MediaQueryData data = MediaQueryData.fromWindow(window);
//设置全屏
SystemChrome.setEnabledSystemUIOverlays([]);
runApp(MaterialApp(
builder: (context,child)=>MediaQuery(
data:MediaQuery.of(context).copyWith(
padding: data.padding,
viewPadding: data.viewPadding,
viewInsets: data.viewInsets,
),
child: child!,
)));
}
这样在widget里面就能正常获取padding了。
但是flutter的启用热加载时,MediaQueryData data = MediaQueryData.fromWindow(window);又获取不到padding了
原因是设置了全屏,我们可以先设置非全屏,然后获取padding,再设置全屏
import 'dart:async';
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
typedef MaterialAppBuilder = Widget Function(TransitionBuilder? transitionBuilder);
void wrapperMain(MaterialAppBuilder builder) async {
WidgetsFlutterBinding.ensureInitialized();
MediaQueryData? data;
if (Platform.isAndroid) {
//热加载启动 top == 0.0 先设置为非全屏模式,延迟500ms去获取,再设置全屏
data = MediaQueryData.fromWindow(window);
if (data.padding.top > 0.0) {
SystemChrome.setEnabledSystemUIOverlays([]);
} else {
//如果获取不到top 先设置为非全屏模式,延迟500ms去获取,再设置全屏
//setEnabledSystemUIOverlays调用间隔至少1秒
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.top, SystemUiOverlay.bottom]);
Timer(Duration(seconds: 1), () {
SystemChrome.setEnabledSystemUIOverlays([]);
});
}
} else {
SystemChrome.setEnabledSystemUIOverlays([]);
}
Widget mediaQueryBuilder(BuildContext context, Widget? child) {
return data!.padding.top > 0.0
? MediaQuery(
child: child!,
data: MediaQuery.of(context).copyWith(
padding: data.padding,
viewPadding: data.viewPadding,
viewInsets: data.viewInsets,
),
)
: AppRootWidget(child: child!);
}
runApp(builder.call(data == null ? null : mediaQueryBuilder));
}
class AppRootWidget extends StatefulWidget {
final Widget child;
const AppRootWidget({Key? key, required this.child}) : super(key: key);
@override
State<StatefulWidget> createState() => _State();
}
///解决android全屏padding为0问题
class _State extends State<AppRootWidget> {
MediaQueryData? _mediaQueryData;
@override
void initState() {
super.initState();
Future.delayed(Duration(milliseconds: 500), () {
_mediaQueryData = MediaQueryData.fromWindow(window);
if (mounted) setState(() {});
});
}
@override
Widget build(BuildContext context) {
final data = _mediaQueryData;
if (data == null) {
return widget.child;
}
return MediaQuery(
child: widget.child,
data: MediaQuery.of(context).copyWith(
padding: data.padding,
viewPadding: data.viewPadding,
viewInsets: data.viewInsets,
),
);
}
}
void main() {
wrapperMain((builder){
return MaterialApp(
onGenerateRoute: routeFactory,
debugShowCheckedModeBanner: false,
builder: builder,
);
});
}
这样就完美了!
|