在Flutter开发中我们知道直接设置宽高数值就能达到适配的效果,那它的屏幕适配机制时这样的呢?
Flutter是如何做屏幕适配的?
在Flutter开发中我们知道直接设置宽高数值就能达到适配的效果,那它的屏幕适配机制时这样的呢?之前的MediaQuery源码分析中我们发现设备有一个devicePixelRatio 这个值是代表单位逻辑像素的物理像素数量,这个定义和Android中的 density 有点像。通过查看源码这个值确实就是 density。关于density的逻辑就不再赘述了,可以去看之前的Android屏幕适配的文章。
Flutter 引擎源码
//shell/platform/android/io/flutter/view/FlutterView.java
public FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
super(context, attrs);
Activity activity = getActivity(getContext());
if (activity == null) {
throw new IllegalArgumentException("Bad context");
}
if (nativeView == null) {
mNativeView = new FlutterNativeView(activity.getApplicationContext());
} else {
mNativeView = nativeView;
}
dartExecutor = mNativeView.getDartExecutor();
flutterRenderer = new FlutterRenderer(mNativeView.getFlutterJNI());
mIsSoftwareRenderingEnabled = mNativeView.getFlutterJNI().nativeGetIsSoftwareRenderingEnabled();
mMetrics = new ViewportMetrics();
// 通过Java代码获取平台中的density值
mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density;
// ...... 省略 ......
}
现在我们知道了 Flutter 的适配方案就是 density,也知道通过 density 适配的弊端,下面我们就直接看一下Flutter中如何修改 devicePixelRatio 来做屏幕适配。
当我们调用 runApp 的时候,会做三件事请 1.实例化WidgetsFlutterBinding类,2.创建组件树attachRootWidget(app),3.启动预热帧scheduleWarnUpFrame()。
void runApp(Widget app) {
WidgetsFlutterBinding.ensureInitialized()
..scheduleAttachRootWidget(app)
..scheduleWarmUpFrame();
}
WidgetsFlutterBinding继承自BindingBase 并混入了很多Binding,其中RendererBinding有个createViewConfiguration,注释也说明可以通过修改这个方法来修改屏幕逻辑尺寸和像素密度。
class AutoWidgetsFlutterBinding extends WidgetsFlutterBinding{
static WidgetsBinding ensureInitialized() {
if (WidgetsBinding.instance == null) AutoWidgetsFlutterBinding();
return WidgetsBinding.instance!;
}
@override
ViewConfiguration createViewConfiguration() {
super.createViewConfiguration();
return ViewConfiguration();
}
}
2139

被折叠的 条评论
为什么被折叠?



