当我们同时为手机和平板适配编写 app 针对不同屏幕尺寸进行 UI 布局或当用户偏好设置较大字号或是想要最大限度等减少动画等;此时就需要 MediaQuery 来帮我们获取所用设备的信息以及用户设置的偏好信息;
十载的耿马网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网整合营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整耿马建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“耿马网站设计”,“耿马网站推广”以来,每个客户项目都认真落实执行。
MediaQuery 一直存在于 WidgetsApp 和 MaterialApp 中, MediaQuery 继承自 InheritedWidget 是一个单独的 Widget ,但一般通过 MediaQuery.of(context) 来获取相关信息;
当相关信息发生变化,例如屏幕旋转等时,屏幕中 Widget 会重新构建,以保持最新状态;我们可以通过 MediaQuery 构造函数和提供的静态方法手动设置对应的相关信息;
MediaQueryData 包含关于媒介的相关信息;一般通过 MediaQuery.of(context) 获取;
size 为媒介的尺寸大小,以逻辑像素为单位;
devicePixelRatio 为像素密度;与设备物理像素有关,与横竖屏等无关;
orientation 为横竖屏, Orientation.landscape 为横屏, Orientation.portrait 为竖屏;
textScaleFactor 为
每个逻辑像素的字体像素数,小菜理解为字体的像素比;注意,小菜设置了默认字体像素密度为标准的 1.2 倍之后调整设备系统字号,其 1.2 倍依旧是以标准字号为基础扩大 1.2 倍;
platformBrightness 为当前设备的亮度模式;注意调整屏幕亮度并不会改变该模式,与当前系统支持的黑暗模式和明亮模式相关;
alwaysUse24HourFormat 为当前设备是否为 24 小时制;
accessibleNavigation 为是否使用 TalkBack 或 VoiceOver 之类的辅助功能与应用程序进行交互,用以辅助视力障碍人群;
invertColors 为是否使用颜色反转,主要用于 iOS 设备;
highContrast 为用户是否要求前景与背景之间的对比度高,主要用于 iOS 设备;
disableAnimations 为平台是否要求禁用或减少动画;
boldText 为平台是否要求使用粗体;
padding 为屏幕内边距,一般是刘海儿屏或异形屏中被系统遮挡部分边距;
viewInsets 为键盘弹出时等遮挡屏幕边距,其中 viewInsets.bottom 为键盘高度;
systemGestureInsets 为手势边距,如 Android Q 之后添加的向左滑动关闭页面等;
viewPadding 小菜理解为视图内边距,为屏幕被刘海儿屏或异形屏中被系统遮挡部分,从 MediaQuery 边界的边缘计算;此值是保持不变;例如,屏幕底部的软件键盘可能会覆盖并占用需要底部填充的相同区域,因此不会影响此值;
physicalDepth 为设备物理层级,小菜暂时还未想到对应的应用场景;
小菜在尝试获取其他子 Widget Size 时,有两点需要注意,首先要设置一个全局的 GlobalKey 来获取当前位置, key 需要为唯一的;第二通过 GlobalKey().currentContext 获取 BuildContext 上下文环境,从而获取对应尺寸;
MediaQuery 案例尝试
小菜对于部分 MediaQueryData 的应用和理解还不够深入;如有错误请多多指导!
结果整个页面都无法滑动,不是我要的效果。如果是有页面不要滑动的那种可以尝试。
使用 vue-bounce 来解决,也没啥用。不知道是不是我打开的方式不对。
安装
使用指令
PS :又尝试了一下,还是有点效果的。就是在顶部进行下拉时会禁用掉 touchmove 事件,但是效果还是不好。因为我可能先往下滑滑不动又往别的方向滑。
灵光一闪,想问下 IOS 端的同学能不能把弹性关了,他给出的解决方案,结合我们 native 端使用了 flutter,给出方案:
我让 native 端的同学进行尝试,结果据 flutter 端同事回复,这个开关只关闭了页面整体边缘的橡皮筋效果,对于 H5 内 div 的边界弹性效果无效。
网上找的方案,明显不对味。
没什么用……感觉这个是解决页面整体弹性滑动的。
使用一个新的 CSS 属性来实现
结果,依旧不行。
使用 来阻止回弹效果,发现效果应该是和 vue-bounce 一样,在用户直接拖拽边缘的时候禁用移动行为,但依然存在来回滑动没反应的情况。
最后通过自己写拖拽滑动,的确解决了这个问题。解决方案在 解决 IOS 13+ H5 滑动边界橡皮筋弹性效果
一文中。
1.动画原理:在一段时间内快速的多次改变UI外观,由于人眼会产生视觉暂留所以最终看到的就是一个连续的动画。
UI的一次改变称为一个动画帧,对应一次屏幕刷新。
FPS:帧率,每秒的动画帧数。
flutter动画分为两类:
常见动画模式:
是一个抽象类,主要的功能是保存动画的值和状态。常用的一个Animation类是Animation double ,是一个在一段时间内依次生成一个区间之间的值的类,可以是线性或者曲线或者其他。
可以生成除double之外的其他类型值,如:Animation Color 或 Animation Size 。
是一个动画控制器,控制动画的播放状态,在屏幕刷新的每一帧,就会生成一个新的值。
包含动画的启动forward()、停止stop() 、反向播放 reverse()等方法,在给定的时间段内线性的生成从0.0到1.0(默认区间)的数字。
curve:描述动画的曲线过程。
curvedAnimation:指定动画的曲线。
常用Curve:
继承自Animatable T ,表示的就是一个 Animation 对象的取值范围,只需要设置开始和结束的边界值(值也支持泛型)。 它唯一的工作就是定义输入范围到输出范围的映射。
例如,Tween可能会生成从红到蓝之间的色值,或者从0到255。
Tween.animate:返回一个Animation。
映射过程:
1). Tween.animation通过传入 aniamtionController 获得一个_AnimatedEvaluation 类型的 animation 对象(基类为 Animation), 并且将 aniamtionController 和 Tween 对象传入了 _AnimatedEvaluation 对象。
2). animation.value方法即是调用 _evaluatable.evaluate(parent)方法, 而 _evaluatable 和 parent 分别为 Tween 对象和 AnimationController 对象。
3). 这里的 animation 其实就是前面的 AnimationController 对象, transform 方法里面的 animation.value则就是 AnimationController 线性生成的 0.0~1.0 直接的值。 在 lerp 方法里面我们可以看到这个 0.0~1.0 的值被映射到了 begin 和 end 范围内了。
接收一个TickerProvider类型的对象,它的主要职责是创建Ticker。
防止屏幕外动画消耗资源。
[图片上传失败...(image-115b94-1636441483468)]
过程:
回调:
不使用addListener()和setState()来给widget添加动画。
使用AnimatedWidget,将widget分离出来,创建一个可重用动画的widget,AnimatedWidget中会自动调用addListener()和setState()
AnimatedModalBarrier、DecoratedBoxTransition、FadeTransition、PositionedTransition、RelativePositionedTransition、RotationTransition、ScaleTransition、SizeTransition、SlideTransition
如何渲染过渡,把渲染过程也抽象出来:
AnimatedBuilder的示例包括: BottomSheet、 PopupMenu、ProgressIndicator、RefreshIndicator、Scaffold、SnackBar、TabBar。
MaterialPageRoute:平台风格一致的路由切换动画
CupertinoPageRoute:左右切换风格
自定义:PageRouteBuilder
1.要创建交织动画,需要使用多个动画对象(Animation)。
2.一个AnimationController控制所有的动画对象。
3.给每一个动画对象指定时间间隔(Interval)
可以同时对其新、旧子元素添加显示、隐藏动画.
当AnimatedSwitcher的child发生变化时(类型或Key不同),旧child会执行隐藏动画,新child会执行执行显示动画。
希望大家支持一下,感谢
页面中的各界面元素(Widget)以树的形式组织,即控件树。Flutter通过控件树中的每个控件创建不同类型的渲染对象,组成渲染对象树。而渲染对象树在Flutter的展示过程分为三个阶段:布局、绘制、合成和渲染。
(一)布局
Flutter采用深度优先机制遍历渲染对象树,决定渲染对象树中各渲染对象在屏幕上的位置和尺寸。在布局过程中,渲染对象树中的每个渲染对象都会接收父对象的布局约束参数,决定自己的大小,然后父对象按照控件逻辑决定各个子对象的位置,完成布局过程。
为了防止因子节点发生变化而导致整个控件树重新布局,Flutter加入了一个机制——布局边界(Relayout Boundary),可以在某些节点自动或手动地设置布局边界,当边界内的任何对象发生重新布局时,不会影响边界外的对象,反之亦然。
二)绘制
布局完成后,渲染对象树中的每个节点都有了明确的尺寸和位置。Flutter会把所有的渲染对象绘制到不同的图层上。与布局过程一样,绘制过程也是深度优先遍历,而且总是先绘制自身,再绘制子节点。
以下图为例:节点1在绘制完自身后,会再绘制节点2,然后绘制它的子节点3、4和5,最后绘制节点6。
可以看到,由于一些其他原因(比如,视图手动合并)导致2的子节点5与它的兄弟节点6处于了同一层,这样会导致当节点2需要重绘的时候,与其无关的节点6也会被重绘,带来性能损耗。
为了解决这一问题,Flutter提出了与布局边界对应的机制——重绘边界(Repaint Boundary)。在重绘边界内,Flutter会强制切换新的图层,这样就可以避免边界内外的互相影响,避免无关内容置于同一图层引起不必要的重绘。
重绘边界的一个典型场景是Scrollview。ScrollView滚动的时候需要刷新视图内容,从而触发内容重绘。而当滚动内容重绘时,一般情况下其他内容是不需要重绘的,这时候重绘边界就派上用场了。
(三)合成和渲染
终端设备的页面越来越复杂,因此Flutter的渲染树层级通常很多,直接交付给渲染引擎进行多图层渲染,可能会出现大量渲染内容的重复绘制,所以还需要先进行一次图层合成,即将所有的图层根据大小、层级、透明度等规则计算出最终的显示效果,将相同的图层归类合并,简化渲染树,提高渲染效率。
合并完成后,Flutter会将几何图层数据交由Skia引擎加工成二维图像数据,最终交由GPU进行渲染,完成界面的展示。
四、总结
咱们从各种业界主流跨端方案与Flutter的对比开始,到Flutter的简要介绍以及Flutter的运行机制,并以界面渲染过程为例,从布局、绘制、合成和渲染三个阶段讲述了Flutter的实现原理。相信大家对Flutter已经有一个整体认知,赶快一起上手操作起来吧!
Image是一个用于展示图片的组件。支持 JPEG、PNG、GIF、Animated GIF、WebP、Animated WebP、BMP 和 WBMP 等格式。
Image.asset - 用于从资源目录的显示图片,需要在 pubspec.yaml 文件中声明。
Image.network - 用于从网络上显示图片。
Image.file - 用于从文件里显示图片。
Image.memory - 用于从内存里(Uint8List)显示图片。
alignment → AlignmentGeometry - 图像边界内对齐图像。
centerSlice → Rect - 九片图像的中心切片。
color → Color - 该颜色与每个图像像素混合colorBlendMode。
colorBlendMode → BlendMode - 用于 color 与此图像结合使用。
fit → BoxFit - 图像在布局中分配的空间。
gaplessPlayback → bool - 当图像提供者发生变化时,是继续显示旧图像(true)还是暂时不显示(false)。
image → ImageProvider - 要显示的图像。
matchTextDirection → bool - 是否在图像的方向上绘制图像 TextDirection。
repeat → ImageRepeat - 未充分容器时,是否重复图片。
height → double - 图像的高度。
width → double - 图像的宽度。
加载资源图片需要将图片资源放入工程中,例如:新建images文件夹,将图片放在该文件夹下,图片适配则是使用ios的方式1X,2X,3X:
然后在pubspec.yaml中配置assets:
加载资源/网络/本地文件图片/内存图片:
占位图加载图片:
圆形图片:1.裁剪实现 2.CircleAvatar实现 3.Container边框实现
圆角图片:1.裁剪实现 2.Container边框实现
BoxFit.contain 全图居中显示但不充满,显示原比例
BoxFit.cover 图片可能拉伸,也可能裁剪,但是充满容器
BoxFit.fill 全图显示且填充满,图片可能会拉伸
BoxFit.fitHeight 图片可能拉伸,可能裁剪,高度充满
BoxFit.fitWidth 图片可能拉伸,可能裁剪,宽度充满
BoxFit.scaleDown 效果和contain差不多, 但是只能缩小图片,不能放大图片
下一节学习基础组件之Text