本方案已废弃,点击查看新方案
关于
MediaQuery引起rebuild的原因及解决方案,可参考京东云团队# Flutter调优--深入探究MediaQuery引起界面Rebuild的原因及解决办法 | 京东云技术团队
那么为什么要有本文,因为上文中给出的解决方案在3.10.2版本中,并不起效。
针对上文中给出的方案:
一、useInheritedMediaQuery
'useInheritedMediaQuery' is deprecated and shouldn't be used.
Remove this parameter as it is now ignored.
Material App never introduces its own MediaQuery; the View widget takes care of that.
This feature was deprecated after v3.7.0-29.0.pre.
在3.10.2中,加入该属性后,出现上面的提示,按照这段提示,3.7.0版本中就已经废弃该属性。
二、使用Builder控件包裹
经实际测试,也并未生效。
我的思路是,在顶层获取状态栏高度、屏幕宽高,存入常量中,后续页面调用所需常量即可。
代码如下:
@override
Widget build(BuildContext context) {
//该方案部分安卓机型会出现丢失问题,可参考新文章
Constants.initializeScreenConstants(context);
return MaterialApp.router(
debugShowCheckedModeBanner: false,
title: '小火箭',
routerConfig: router(),
builder: EasyLoading.init(),
),
);
}
对应Constants.dart
import 'package:flutter/material.dart';
class Constants {
static late double stateHeight;
static late double screenHeight;
static late double screenWidth;
static void initializeScreenConstants(BuildContext context){
//使用 MediaQueryData.fromView(View.of(context))
//不要用 MediaQuery.sizeOf(context)
//这两者是有区别的
//In a utility class or a custom function,要使用MediaQueryData.fromView(View.of(context)).
var currentView = MediaQueryData.fromView(View.of(context));
stateHeight = currentView.padding.top;
screenWidth = currentView.size.width;
screenHeight = currentView.size.height;
}
}
引用时,只需调用Constants.stateHeight即可,记得要引入Constants.dart。
通过将调用MediaQuery的操作前置,避免了在UI组件中调用MediaQuery,达到消除rebuild的目的,包括键盘弹出引起的rebuild问题,因为UI组件中已经没有MediaQuery的地方。
关于键盘弹出,引起rebuild问题
在调研过程中,发现将输入框直接包裹在GestureDetector中,并添加behavior属性,将其置为HitTestBehavior.opaque,也可以解决rebuild问题。代码如下:
GestureDetector(behavior:HitTestBehavior.opaque,child:TextField(),);
总结
大胆假设,小心求证,不断调整,快速迭代。