当前位置: 首页 > news >正文

企业网站 阿里云新闻发布最新新闻

企业网站 阿里云,新闻发布最新新闻,专业的vi设计企业,中华建设一、滚动布局 Flutter中可滚动布局基本都来自Sliver模型#xff0c;原理和安卓传统UI的ListView、RecyclerView类似#xff0c;滚动布局里面的每个子组件的样式往往是相同的#xff0c;由于组件占用内存较大#xff0c;所以在内存上我们可以缓存有限个组件#xff0c;滚动…一、滚动布局 Flutter中可滚动布局基本都来自Sliver模型原理和安卓传统UI的ListView、RecyclerView类似滚动布局里面的每个子组件的样式往往是相同的由于组件占用内存较大所以在内存上我们可以缓存有限个组件滚动布局时仅仅刷新组件的数据来达到滚动布局存放无限个子组件的目标。另一方面内容被渲染到了lazy widget里也就是SliverList and SliverGrid (以及它们的变种 SliverFixedExtentList 和 SliverAnimatedGrid。这些组件确保只有列表中可见部分会被布局和渲染。ListView 和 GridView只是CustomScrollView 和 SliverList 或 SliverGrid组合在一起方便我们使用的一个封装组件而已。它们允许我们直接使用box widget。而CustomScrollView的slivers属性明确要求我们使用sliver widget。但是sliver widget也只是box widget的包裹后者才是真正用于渲染的。按照列表内容的差异我们可以将scrolling widget分为以下三类 sliver widget是可滚动列表中的一部分它是面向viewport进行布局的。 二、ViewPort ViewPort 是一个显示窗口它内部可包含多个 SliverViewPort 的宽高是确定的它内部 Slivers 的宽高之和是可以大于自身的宽高的ViewPort 为了提高性能采用懒加载机制它只会绘制可视区域内容 Widget。 ViewPort 有一些重要属性 class Viewport extends MultiChildRenderObjectWidget {/// 主轴方向final AxisDirection axisDirection;/// 纵轴方向final AxisDirection crossAxisDirection;/// center 决定 viewport 的 zero 基准线也就是 viewport 从哪个地方开始绘制默认是第一个 sliver/// center 必须是 viewport slivers 中的一员的 keyfinal Key center;/// 锚点取值[0,1]和 zero 的相对位置比如 0.5 代表 zero 被放到了 Viewport.height / 2 处final double anchor;/// 滚动的累计值确切的说是 viewport 从什么地方开始显示final ViewportOffset offset;/// 缓存区域也就是相对有头尾需要预加载的高度final double cacheExtent;/// children widgetListWidget slivers} 我们看到center是一个key表示从哪个sliver开始绘制绘制的起点是一条zero基准线。这条基准线相对于视口的位置叫anchor。视口相对于整个滚动列表的位置叫offset。如果子元素进入了视口上下cacheExtent的区域就会被预先加载。 以上图为例centersliver1anchor0.2此时sliver的top0.2 * viewport.height所以前面刚好能展示sliver0也就是浅蓝色区域会滚到整个列表的开始位置。再比如centersliver1anchor0.4此时sliver0上面会空出一条sliver大小的空间。 三、SliverConstraints 和 Box 布局使用 BoxConstraints 作为约束类似Sliver 布局采用 SliverConstraints 作为约束但相对于 Box 要复杂的多可以理解为 SliverConstraints 描述了 Viewport 和它内部的 Slivers 之间的布局信息 class SliverConstraints extends Constraints {//主轴方向AxisDirection? axisDirection;//Sliver 新数据沿主轴的哪个方向插入枚举类型正向或反向GrowthDirection? growthDirection;//用户滑动方向ScrollDirection? userScrollDirection;//当前Sliver理论上可能会固定在顶部已经滑出可视区域的总偏移double? scrollOffset;//当前Sliver之前的Sliver占据的总高度因为列表是懒加载如果不能预估时该值为double.infinitydouble? precedingScrollExtent;//上一个 sliver 覆盖当前 sliver 的大小通常在 sliver 是 pinned/floating//或者处于列表头尾时有效。double? overlap;//当前Sliver在Viewport中的最大可以绘制的区域。//绘制如果超过该区域会比较低效因为不会显示double? remainingPaintExtent;//纵轴的长度如果列表滚动方向是垂直方向则表示列表宽度。double? crossAxisExtent;//纵轴方向AxisDirection? crossAxisDirection;//Viewport在主轴方向的长度如果列表滚动方向是垂直方向则表示列表高度。double? viewportMainAxisExtent;//Viewport 预渲染区域的起点[-Viewport.cacheExtent, 0]double? cacheOrigin;//Viewport加载区域的长度范围://[viewportMainAxisExtent,viewportMainAxisExtent Viewport.cacheExtent*2]double? remainingCacheExtent; }cacheOrigin 在Viewport 预渲染区域中的起点位于[-Viewport.cacheExtent, 0]之间 overlap 上图中的 sliver1 会被 SliverAppBarpinned true遮住遮住的大小就是 overlap此时 overlap 会一直大于 0如果设置像 iOS bouncing 那样的滑动效果那么当 list 滚动到顶部继续滑动的时候 overlap 会小于 0此刻并没有东西遮盖 sliver1而是 sliver1 的 top 和 viewport 的 top 有间距。 remainingPaintExtent 当前 Sliver 在 Viewport 中的最大可以绘制的区域。当viewport对sliver布局的时候会将remainingPaintExtent减去这个sliver的paintExtent后作为传入下一个sliver的remainingPaintExtent。remainingPaintExtent的初始值是viewportMainAxisExtent。 由此我们可以计算当前 sliver 距离顶部的距离 //如果大于0表示当前 sliver 距离顶部的高度为 topOffset。若已经到达顶部或超出顶部则该值始终等于 0。此时超出的距离可参考 scrollOffset。 topOffset viewportMainAxisExtent - remainingPaintExtent;当前sliver无论实际需要绘制多大的区域最终能绘制到viewport的大小不会超过remainingPaintExtent // paintExtent 通常需要这样处理一下避免超出 remainingPaintExtent paintExtent min(paintExtent, constraints.remainingPaintExtent);scrollOffset scrollOffset 属性表示滚动滑出Viewport边界的距离类似于 web 的 scrollTop 属性。一般来说表示组件的上边界离开 viewport 顶部的长度未到达顶部之前都是 0。 SliverGeometry Viewport 通过 SliverConstraints 告知它内部的 sliver 自己的约束信息比如还有多少空间可用、offset 等那么Sliver 则通过 SliverGeometry 反馈给 Viewport 需要占用多少空间量。 const SliverGeometry({//Sliver在主轴方向预估长度大多数情况是固定值用于计算sliverConstraints.scrollOffsetthis.scrollExtent 0.0, this.paintExtent 0.0, // 可视区域中的绘制长度this.paintOrigin 0.0, // 绘制的坐标原点相对于自身布局位置//在 Viewport中占用的长度如果列表滚动方向是垂直方向则表示列表高度。//范围[0,paintExtent]double? layoutExtent, this.maxPaintExtent 0.0,//最大绘制长度this.maxScrollObstructionExtent 0.0,double? hitTestExtent, // 点击测试的范围bool? visible,// 是否显示//是否会溢出Viewport如果为trueViewport便会裁剪this.hasVisualOverflow false,//scrollExtent的修正值layoutExtent变化后为了防止sliver突然跳动应用新的layoutExtent//可以先进行修正。this.scrollOffsetCorrection,double? cacheExtent, // 在预渲染区域中占据的长度 }) paintOrigin 当该值小于 0 时当前 sliver 的整体起始位置会向上偏移 paintOrigin.abs() 的长度。如果每次下拉 x 的长度paintOrigin 也向上移动 x 的距离则 sliver 相对静止由此可实现 pinned 效果。 layoutExtent 布局时占用的高度取值范围 [0, paintExtent]。即 layoutExtent 须小于等于 paintExtent 当前绘制的高度一般是等于。 当 layoutExtent 小于 paintExtent 时则一部分高度会被下一个 sliver 顶上。 示例 2 说明蓝色块高度是 100但是占据高度只有 30导致红色块向上顶了 70的高度。紫色部分是下方的红色与上方的蓝色重叠的区域 visible 当 visible 为 false 时会影响子节点的显示。在示例中只占据空间占据高度 layoutExtent而不显示界面。即不影响布局。 效果 说明中间 30 的高度为原蓝色块占据的空间 scrollExtent 可滚动的范围。一般来说对于 ListView在 sliver 上边界滚动到顶部之前 paintExtent 等于 layoutExtent 都等于 scrollExtent到达顶部后慢慢变小直到变为 0。而 scrollExtent 一直不变。 注如果 layoutExtent 不慢慢变小即保持不变并且大于 0则在当前 sliver 滚动到顶部后还可以继续滚动 scrollExtent 的长度除非 scrollExtent 也等于 0然后再执行下一个 sliver 的滚动。 示例 3 说明由于 layoutExtent 与 scrollExtent 都一直不变并且不等于 0。蓝色 sliver 向上滚动到 Viewport 顶部后还可以继续滚动 100 的高度当这 100 也滚完了下一个 sliver 才开始滚动。 Sliver 布局过程 RenderViewport 在 layout 它内部的 slivers 的过程如下 这个 layout 过程是一个自上而下的线性过程 给 sliver1 输入 SliverConstrains1 并且得到输出结果SliverGeometry1 根据 SliverGeometry1 重新生成一个新的 SliverConstrains2 输入给 sliver2 得到 SliverGeometry2…直至最后一个 sliver 具体的过程可以查看 RenderViewport 的 layoutChildSequence 方法。 Slivers Flutter 提供了很多的 Sliver 组件下面我们主要说一下它们的作用是什么 SliverAppBar 类似于 android 中 CollapsingToolbarLayout可以根据滑动做伸缩布局并提供了 actionsbottom 等提高效率的属性。 SliverList / SliverGrid 用法和 ListView / GridView 基本一致。 此外ListView SliverList Scrollable也就是说 SliverList 不具备处理滑动事件的能力所以它必须配合 CustomScrollView 来使用。 SliverFixedExtentList 它比 SliverList 多了修饰词 FixedExtent意思是它的 item 在主轴方向上具有固定的高度/宽度。 设计它的原因是在 item 高度/宽度全都一样的场景下使用它的效率比 SliverList 高因为它不用通过 item 的 layout 过程就可以知道每个 item 的范围。 在使用的时候必须传入 itemExtent SliverFixedExtentList(itemExtent: 50.0,delegate: SliverChildBuilderDelegate(...);},), ) SliverPersistentHeader SliverPersistentHeader 是一个可以固定/悬浮的 header它可以设置在列表的任意位置显示的内容需要设置 SliverPersistentHeaderDelegate。 SliverPersistentHeader(pinned: true,delegate: ..., )SliverPersistentHeaderDelegate 是一个抽象类我们需要自己实现它它的实现很简单只有四个必须要实现的成员 class CustomDelegate extends SliverPersistentHeaderDelegate {/// 最大高度overridedouble get maxExtent 100;/// 最小高度overridedouble get minExtent 50;/// shrinkOffset: 当前 sliver 顶部越过屏幕顶部的距离/// overlapsContent: 下方是否还有 content 显示overrideWidget build(BuildContext context, double shrinkOffset, bool overlapsContent) {return your widget);}/// 是否需要刷新overridebool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {return maxExtent ! oldDelegate.maxExtent ||minExtent ! oldDelegate.minExtent;} }在实际运用中沉浸式的设计是很常见的使用 SliverPersistentHeaderDelegate 可以轻松的实现沉浸式的效果 它的实现原理就是根据 shrinkOffset 动态调整状态栏的样式和标题栏的颜色实现代码见下面的 沉浸式 Header。 SliverToBoxAdapter 将 BoxWidget 转变为 Sliver由于 CustomScrollView 只能接受 Sliver 类型的 child所以很多常用的 Widget 无法直接添加到 CustomScrollView 中此时只需要将 Widget 用 SliverToBoxAdapter 包裹一下就可以了。 最常见的使用就是 SliverList 不支持横向模式但是又无法直接将 ListView 直接添加到 CustomScrollView 中此时用 SliverToBoxAdapter 包裹一下 CustomScrollView(slivers: Widget[SliverToBoxAdapter(child: _buildHorizonScrollView(),),],));Widget _buildHorizonScrollView() {return Container(height: 50,child: ListView.builder(scrollDirection: Axis.horizontal,primary: false,shrinkWrap: true,itemCount: 15,itemBuilder: (context, index) {return Container(color: ColorUtils.randomColor(),width: 50,height: 50,);}),);} SliverPadding 可以用在 CustomScrollView 中的 Padding。 需要注意的是不要用它来包裹 SliverPersistentHeader 因为它会使 SliverPersistentHeader 的 pinned 失效如果 SliverPersistentHeader 非要使用 Padding 效果可以在 delegate 内部使用 Padding。 wrong code SliverPadding(padding: EdgeInsets.symmetric(horizontal: 16),sliver: SliverPersistentHeader(pinned: true,floating: false,delegate: Delegate(),),) correct code class Delegate extends SliverPersistentHeaderDelegate {overrideWidget build(BuildContext context, double shrinkOffset, bool overlapsContent) Padding(padding: EdgeInsets.symmetric(horizontal: 16),child: Container(color: Colors.yellow,),);... }SliverSafeArea 用法和 SafeArea 一致。 SliverFillRemaining 可以填充屏幕剩余控件的 Sliver。 参考文献 Flutter - 循序渐进 Sliver - 掘金flutter —— 布局原理与约束 Sliver 布局
http://www.zqtcl.cn/news/272349/

相关文章:

  • 郑州企业建站系统模板兰州需要做网站的公司有哪些
  • 怎样做网站卖东西 自己有货句容网络公司
  • 网站建设协议书 保密条款免费发布推广的网站
  • 网站首页外链上海网站建设联系方式
  • 陕西网站建设优化技术2023年1月热点新闻事件
  • 广东省建设银行招聘网站免费搭建个人网站
  • 知名商城网站建设公司wordpress主题 汉化
  • 网站上线做什么pc网站如何做移动适配
  • wap网站搭建北京北京网站建设
  • 放心的网站设计制作免费做logo设计的网站
  • 温州专业手机网站制作多少钱移动商城 网站建设方法方式
  • 周口网站开发wordpress
  • 如何查网站的备案号玉环在哪里做网站
  • 网站开发什么叫前端后端seo研究中心晴天
  • 邢台建筑类的建设网站代刷网站只做软件下载
  • 关于旅游的网站建设目的食品网站建设的目的
  • 开发php网站开发太湖网站建设推荐秒搜科技
  • 90设计网站怎么绑定手机号淘宝搜索排名
  • 无锡自助做网站哪些编程语言适合网站开发
  • 蒲城网站建设wzjseo北京专业推广公司
  • 阳春做网站外贸建站推广公司
  • 哪个网站的课件做的好源码之家关闭了
  • 各大网站热搜榜排名嵊州网站
  • 在哪找做网站的镇江网页设计工作室
  • 做网站的是干嘛的百度推广的几种方式
  • 临沧网站建设用eclipse做jsp网站
  • 做物流运输网站电话做网站看
  • 山东公司网站推广优化什么网站做宣传好
  • 企业网站模板设计外网vp(永久免费)加速器下载
  • 消费者联盟网站怎么做中山网站建设案例