一个Flutter widget自动适配不同UI到Web、And
2020-03-22 本文已影响0人
i校长
上图
webUIandroidUI
不是dp适配
对的,不是对dp的适配,而是在不同的分变率,改变布局的方式。大的屏幕肯定是要合理利用空间,这样布局紧凑,不浪费空间,小的屏幕又不能让大的组件等比压缩,这样不光会变丑,还会变的更难触及,既然Flutter对web的支持,那么肯定要支持不同分辨率,适配不同布局吧,就像我们Android开发,在针对Pad的时候做一个单独的xml布局来适配一样。
实现原理
原理很简单,就是在屏幕宽度到了一定范围内,然后动态返回不同的Widget,那么拿到屏幕的宽度就是关键,其实很简单
MediaQuery.of(context).size.width
详细介绍参见官方文档MediaQuery
大致意思是说,WidgetsApp和MaterialApp目前只有它们引入了MediaQuery并随着它们的变化与当前屏幕指标保持最新,所以这也是为什么当你没有用这两个widget布局,最终报错的原因,用的时候注意。
我们来看个细节哈
MaterialApp
WidgetsApp和MaterialApp
继承自StatefulWidget,我们平时写的组件也大部分都是继承自StatefulWidget,所以这就说明,你平时自己写的组件,如果是一个单独的新页面,当你用到这个MediaQuery时肯定会报错,不信你试试哈。
我们知道宽度后就好说了,只需要加入宽度判断就ok
static bool isSmallScreen(BuildContext context) {
return MediaQuery.of(context).size.width < 768;
}
static bool isLargeScreen(BuildContext context) {
return MediaQuery.of(context).size.width > 768;
}
static bool isMediumScreen(BuildContext context) {
return MediaQuery.of(context).size.width > 425 &&
MediaQuery.of(context).size.width < 1200;
}
然后在Widget build(BuildContext context)的时候返回不同的布局
return LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > 768) {
return largeScreen;
} else if (constraints.maxWidth < 1200 && constraints.maxWidth > 425) {
return mediumScreen ?? largeScreen;
} else {
return smallScreen ?? largeScreen;
}
},
);
如何使用呢
ConstrainedBox(
constraints: BoxConstraints(
minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
child: ResponsiveWidget(
largeScreen: _buildLargeScreen(context),
mediumScreen: _buildMediumScreen(context),
smallScreen: _buildSmallScreen(context),
),
)
ConstrainedBox用于对子组件添加额外的约束,这里就是为了限制布局的宽高都充满屏幕,准确的说是充满父容器,保证计算的宽度不会出现失误。
官方动态适配方案
官方解读:
responsive响应式应用程序会根据屏幕或窗口的大小和形状来布局其UI。当同一个应用程序可以在各种设备(从手表,手机,平板电脑到笔记本电脑或台式机)上运行时,这尤其必要。当用户在笔记本电脑或台式机上调整窗口大小或更改手机或平板电脑的方向时,应用程序应通过相应地重新排列UI来做出响应。
官方推荐博客:
- Deven Joshi 在Flutter中开发多种屏幕尺寸和方向
- 在Flutter中构建响应式UI,作者Raouf Rahiche
- Priyanka Tyagi 使跨平台的Flutter登陆页面具有响应性
- 如何使Flutter应用根据不同的屏幕尺寸做出响应?,关于StackOverflow的问题
国外开源方案
image.pngresponsive_builder这个框架的原理跟我介绍的一样,封装的会详细一些。请参考。
我介绍的方案地址
在线看效果
结束
以后碰到Flutter中实用的东东,在分享给你们哈。欢迎留言讨论。