flutter布局(列表组件)
通用ScrollController
-
控制器加上必先挂载销毁
/// 初始化 ScrollController _scrollController = ScrollController(); /// 销毁控制器 @override void dispose(){ _scrollController.dispose(); super.dispose(); } /// 绑定 ListView( controller:_scrollController, //绑定控制器 ) -
滚动到顶部/指定位置
/// 安全判断 if(!_scrollController.hasClients) return; /// 滚动到顶部 _scrollController.jumpTo(0); /// 跳转到顶部,无动画 _scrollController.animateTo( /// 动画滚动 0, duration: const Duration(molliseconds:300), // curve:Curves.easeOut, // 动画曲线 ) /// 滚动至底部(_scrollController.position.maxScrollExtent) final maxExtent = _scrollController.position.maxScrollExtent; _scrollController.jumpTo(maxExtent); ... -
滚动吸顶/隐藏导航栏/下拉更多等
/// 监听+状态 _scrollController.addListener((){ /// 底部200px 触发加载 double maxExtent = _scrollController.position.maxScrollExtent; double currentOffset = _scrollController.offset;/// 滚动到的位置 if(currentOffset >= maxExtent - 200 && !isloading) { loadMoreDate(); } /// 吸顶 if(currentOffset <= 50){ setState({ isCeilingMounted = true; }) }else{ setState({ isCeilingMounted = false; }) } }) -
常用api
-
判定是否有挂载
_scrollController.hasClients -
卸载
_scrollController.dispose(); -
当前滚动位置
_scrollController.offset _scrollController.position.pixels -
列表最大滚动位置
_scrollController.position.maxScrollExtent; -
滚动
_scrollController.jumpTo(); _scrollController.animateTo( 0, duration:const Duration(milliseconds:300), curve: Curves.ease ) -
滚动监听
_scrollController.addListener((){ })
-
列表组件
ListView/ListView.builder/ListView.separated
-
共用api
scrollDirection //默认Axis.vertical(垂直) Axis.horizontal(水平) reverse // 默认false padding // 默认null shrinkWrap // 高度自适应 默认false,性能慎用! controller // 控制器 itemExtent //固定子项高度/宽度 cacheExtent // 预渲染缓存区域大小 prototypeItem // 按照样本组件自适应高度 addautomaticKeepAlives //默认true 保持已经加载好的子项状态,防止滑出屏幕后重建 physics // 滚动物理效果 ///ClampingScrollPhysics(边界“撞墙”+微光效果 安卓默认) ///BouncingScrollPhysics(弹性回弹效果 IOS默认) ///NeverScrollableScrollPhysics(禁止滚动) ///AlwaysScrollableScrollPhysics(强制可滚动) ///PageScrollPhysics(以整页滑动、吸附效果明显)
补充全局效果设置:MaterialApp( scrollBehavior: MaterialScrollBehavior().copyWith( physics: const ClampingScrollPhysics(), // 全平台强制使用Android效果 ), );
-
列表不超过15条可用ListView
-
重点属性
- ListView.builder——只创建/渲染屏幕可见区域+附近区域(超过15条考虑使用)
- itemExtent——告知每一项的宽度/高度,提高命中率和性能(必用)
- control——控制滚动
- scrollDirection——Axis.horizontal/Axis.vertical控制滚动方向
- itemExtent——列表长度
- builder/separated专属(itemCount+itemBuilder)
-
ListView.separated
ListView.separated( itemExtent:, itemCount:, itemBuilder:(context,index), separatorBuilder:(context,index){ return Padding() } ) -
性能优化相关
- ListView.builder/ListView.separated(必需)
- itemExtent (尽量必需,性能最好)
- cacheExtent (必需,但值不能太大)
- addAutomaticKeepAlives: true (通常必需)
- shrinkWrap:true (性能消耗大,慎用!!!)
GridView/GridView.builder/GridView.extent
-
gridDelegate
SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, // 强制2列 mainAxisSpacing: 10, // 上下间距10px crossAxisSpacing: 10, // 左右间距10px childAspectRatio: 1.5, // 子项宽高比 ) SliverGridDelegateWithMaxCrossAxisExtent( // 设置子项的最大宽度,即如果屏幕宽度有500,则(150*n)+(10*(n-1))<=500 maxCrossAxisExtent: 150, // 子项最大宽度150px mainAxisSpacing: 10, // 上下间距10px crossAxisSpacing: 10, // 左右间距10px childAspectRatio: 1.0, // 正方形 ) -
GridView.extent 即透传了 SliverGridDelegateWithMaxCrossAxisExtent,可以直接在GridView.extent中写SliverGridDelegateWithMaxCrossAxisExtent的属性
GridView.extent( controller:_controller, children:<Widget>[], double maxCrossAxisExtent, double mainAxisSpacing, double crossAxisSpacing, double? childAspectRatio )
SingleChildScrollView
- 较短的滚动页面(长列表情况性能消耗较大)
- 通常用作页面防溢出或短滚动
CustomScrollView
- 大部分属性跟ListView和GridView一样,下面只例举较常用的api
- cacheExtent(默认250)可设置150左右
- shrinkWrap(是否自适应子组件高度)——会破坏懒加载,性能变差
- slivers
- SliverAppBar——折叠式标题栏,支持悬浮、吸顶、折叠
- SliverList——对应ListView
- SliverGrid——对应GridView
- SliverToBoxAdapter——将普通Widget作为child传入Sliver
- SliverPadding——内边距
- SliverFillRemaining——填充页面剩余空间