符合中小企业对网站设计、功能常规化式的企业展示型网站建设
本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...
商城网站建设因基本功能的需求不同费用上面也有很大的差别...
手机微信网站开发、微信官网、微信商城网站...
白话:基于Sliver模型是高性能的,只有出现在可视范围内的组件才够构建,界面外的组件不构建。
网站建设哪家好,找创新互联!专注于网页设计、网站建设、微信开发、小程序开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了合肥免费建站欢迎大家使用!
官话:Flutter中提出一个Sliver(中文为“薄片”的意思)概念,如果一个可滚动组件支持Sliver模型,那么该滚动可以将子组件分成好多个“薄片”(Sliver),只有当Sliver出现在视口中时才会去构建它,这种模型也称为“基于Sliver的延迟构建模型”。
可滚动组件中有很多都支持基于Sliver的延迟构建模型,如ListView、GridView,CustomScrollView但是也有不支持该模型的,如SingleChildScrollView(性能很低,所有UI都会完整的绘制)。
CustomScrollView是可以使用Sliver来自定义滚动模型(效果)的组件。它可以包含多种滚动模型。CustomScrollView可以实现把多个彼此独立的可滑动widget组合起来,并且是高性能的。
CustomScrollView可以控制SliverListView根据需要才构建item,类似与分页加载,复用加载,数据量比较大的时候对提高加载效率非常有帮助。
CustomScrollView:高性能,懒加载,只构建屏幕可视范围内组件,超出屏幕外的组件等滑动的时候再构建,适用于子widget数据量较大的场景。
SingleChildScrollView:低性能,完整加载,直接把整个child完整的构建出来,只适用于子widget数量有限的场景。
我们用CustomScrollView把“导航栏”和“瀑布流”组合在一起,并且依然保持很好的滚动性能。
CustomScrollView下使用的listview也必须是基于sliver模型的,如SliverMasonryGrid,SliverListView,SliverGridView,这样CustomScrollView可以计算listview中需要构建的items。非Sliver组件需要用SliverToBoxAdapter包起来。
瀑布流Demo如下:
实践效果:
GridView可以构建一个二维网格列表
默认构造函数如下:
我们可以看到,GridView和ListView的大多数参数都是相同的,它们的含义也都相同的。我们唯一需要关注的是gridDelegate参数,类型是SliverGridDelegate,它的作用是控制GridView子组件如何排列(layout)。
SliverGridDelegate 是一个抽象类,定义了GridView Layout相关接口,子类需要通过实现它们来实现具体的布局算法。Flutter中提供了两个 SliverGridDelegate 的子类 SliverGridDelegateWithFixedCrossAxisCount 和 SliverGridDelegateWithMaxCrossAxisExtent
SliverGridDelegateWithFixedCrossAxisCount
该子类实现了一个横轴为固定数量子元素的layout算法,其构造函数为:
可以发现,子元素的大小是通过crossAxisCount和childAspectRatio两个参数共同决定的。注意,这里的子元素指的是子组件的最大显示空间,注意确保子组件的实际大小不要超出子元素的空间。
示例
SliverGridDelegateWithMaxCrossAxisExtent
该子类实现了一个横轴子元素为固定最大长度的layout算法,其构造函数为
maxCrossAxisExtent为子元素在横轴上的最大长度,之所以是“最大”长度,是因为横轴方向每个子元素的长度仍然是等分的,举个例子,如果ViewPort的横轴长度是450,那么当maxCrossAxisExtent的值在区间[450/4,450/3)内的话,子元素最终实际长度都为112.5,而childAspectRatio所指的子元素横轴和主轴的长度比为最终的长度比。其它参数和SliverGridDelegateWithFixedCrossAxisCount相同。
示例
GridView.count构造函数内部使用了SliverGridDelegateWithFixedCrossAxisCount,我们通过它可以快速的创建横轴固定数量子元素的GridView
示例
GridView.extent构造函数内部使用了SliverGridDelegateWithMaxCrossAxisExtent,我们通过它可以快速的创建横轴子元素为固定最大长度的的GridView
示例
上面我们介绍的GridView都需要一个widget数组作为其子元素,这些方式都会提前将所有子widget都构建好,所以只适用于子widget数量比较少时,当子widget比较多时,我们可以通过GridView.builder来动态创建子widget。GridView.builder 必须指定的参数有两个:
示例
假设我们需要从一个异步数据源(如网络)分批获取一些Icon,然后用GridView来展示:
_retrieveIcons():在此方法中我们通过Future.delayed来模拟从异步数据源获取数据,每次获取数据需要200毫秒,获取成功后将新数据添加到_icons,然后调用setState重新构建。
在 itemBuilder 中,如果显示到最后一个时,判断是否需要继续获取数据,然后返回一个Icon。
GridView.builder 源码定义如下:
它主要要传两个参数 gridDelegate 和 childrenDelegate ,gridDelegate是SliverGridDelegate类型,SliverGridDelegate它有两个子类,就是我们上文中说的 SliverGridDelegateWithFixedCrossAxisCount 和 SliverGridDelegateWithMaxCrossAxisExtent ,childrenDelegate 是SliverChildDelegate类型,SliverChildDelegate也有两个子类 SliverChildBuilderDelegate 和 SliverChildListDelegate ,一个是通过Builder创建Item,一个是指定所有item。和ListView 很类似
示例
补充知识点:
GridView中的Sliver是SliverGrid
ListView 和 GridView 都是继承于BoxScrollView,BoxScrollView中存在一个抽象方法buildChildLayout,这个buildChildLayout方法是在提供Sliver,GridView中关于buildChildLayout实现如下:
import 'package:flutter/material.dart';
main() = runApp(KSJMyApp());
class KSJMyAppextends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyApp(),
);
}
}
class MyAppextends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('KSJ'),
),
body: NewCountGridViewNewWidget(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
print("+++");
}),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
class NewCountGridViewNewWidgetextends StatelessWidget {
const NewCountGridViewNewWidget({
Key key,
}) :super(key: key);
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisCount:9,
crossAxisSpacing:5,
mainAxisSpacing:10,
children: List.generate(100, (index) {
return Container(
color: index %2 ==0 ? Colors.red : Colors.blue,
);
}),
);
}
}
class GridViewMaxExtentNewWidgetextends StatelessWidget {
const GridViewMaxExtentNewWidget({
Key key,
}) :super(key: key);
@override
Widget build(BuildContext context) {
return GridView(
padding: EdgeInsets.symmetric(horizontal:8, vertical:5),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent:100,
mainAxisSpacing:10,
crossAxisSpacing:20,
childAspectRatio:0.5),
children: List.generate(1000, (index) {
return Container(
color: index %2 ==0 ? Colors.red : Colors.blue,
);
}),
);
}
}
class GridViewDemo1NewWidgetextends StatelessWidget {
const GridViewDemo1NewWidget({
Key key,
}) :super(key: key);
@override
Widget build(BuildContext context) {
return GridView(
// 以自身宽度为基准
// gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: 35),
// 以Item个数为基准
padding: EdgeInsets.symmetric(horizontal:8, vertical:5),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount:5,
mainAxisSpacing:5,
crossAxisSpacing:5,
childAspectRatio:0.1,
),
children: List.generate(1000, (index) {
return Container(
color: index %2 ==0 ? Colors.red : Colors.blue,
);
}),
);
}
}
用 Expanded 和 TextOverflow.clip
Widget testText() {
return GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: 8,
itemBuilder: (BuildContext context, int index) {
return Expanded(
child: Text(
"测试两行测试两行测测试两行测试两行测试两行测试两行测试两行测试两行测试两行测两行测试两行测试两行测试两行测试两行测试两行测试两行",
overflow: TextOverflow.clip,
style: TextStyle(fontSize: 20),
));
},
);
}