1. 介绍一下 5 个新的 Sliver 组件
在 Flutter 3.13 更新中,增加了 5 位新的 Sliver 相关组件,用于滑动视口中,完成特定功用。这篇文章将介绍一下它们的作用和运用场景。
组件名 | 中文名 | 介绍 |
---|---|---|
SliverMainAxisGroup | 主轴分组滑片 | 能够包容多个 Sliver 组件,在主轴方向上分组 |
DecoratedSliver | 装修滑片 | 对 Sliver 进行装修 |
SliverConstrainedCrossAxis | 穿插轴束缚滑片 | 穿插轴方向上固定某个 Sliver的尺度 |
SliverCrossAxisExpanded | 穿插轴延展滑片 | 穿插轴方向上设置某个 Sliver的尺度占比 |
SliverCrossAxisGroup | 穿插轴分组滑片 | 能够包容多个 Sliver 组件,在穿插轴方向上分组 |
这五个组件的运用事例,将在后续加入到开源项目 FlutterUnit 中,欢迎大家对项目的重视和支持 ~
2. 主轴滑片分组: SliverMainAxisGroup 组件
在 《Flutter 滑动探索 – 珠联璧合#第九章》 介绍过一个分组的滑动作用,其时运用了 flutter_sticky_header 三方库来完成的。现在官方提供了 SliverMainAxisGroup 组件,就能够很轻松地完成滑片分组的作用。
详细运用场景是: 比方下面是 QQ
中分组列表滑动作用,组名下有若干成员,组的标题在滑动中会进行吸附,并且在滑动到下一组标题时,上一标题会被滑出;同样,下滑时展示也是如此。
上滑作用 | 下滑作用 |
---|---|
下面,咱们将根据 SliverMainAxisGroup 组件完成下面作用:
上滑作用 | 下滑作用 |
---|---|
首先预备一下数据,作为界面的填充内容:
class ItemData {
final String groupName;
final List<String> users;
ItemData({required this.groupName, this.users = const []});
static List<ItemData> get testData => [
ItemData(groupName: '幻将术士', users: ['梦小梦', '梦千']),
ItemData(
groupName: '幻将剑客', users: ['捷特', '龙少', '莫向阳', '何解连', '浪封', '梦飞烟']),
ItemData(groupName: '幻将弓者', users: ['巫缨', '巫妻孋', '摄王', '裔王', '梦童']),
ItemData(
groupName: '其他', users: List.generate(20, (index) => '小兵$index')),
];
}
然后在组件中经过数据,映射出 SliverMainAxisGroup 列表,每个 SliverMainAxisGroup 列表中能够包容若干个 Sliver 滑块,只要让标题经过 SliverPersistentHeader 吸顶即可:
class MyHomePage extends StatelessWidget{
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('SliverMainAxisGroup')),
body: CustomScrollView(
slivers: ItemData.testData.map(_buildGroup).toList(),
),
);
}
Widget _buildGroup(ItemData itemData) {
return SliverMainAxisGroup(slivers: [
SliverPersistentHeader(
pinned: true,
delegate: HeaderDelegate(itemData.groupName),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => _buildItemByUser(itemData.users[index]),
childCount: itemData.users.length,
),
),
]);
}
Widget _buildItemByUser(String user) {
return Container(
alignment: Alignment.center,
height: 56,
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 20, right: 10.0),
child: FlutterLogo(size: 30),
),
Text(
user,
style: const TextStyle(fontSize: 16),
),
],
),
);
}
}
下面是吸顶标题的代理类,这样总共不到百行代码,就完成了分组滑动的作用,能够说是很便利的。
class HeaderDelegate extends SliverPersistentHeaderDelegate {
const HeaderDelegate(this.title);
final String title;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
alignment: Alignment.centerLeft,
color: const Color(0xffF6F6F6),
padding: const EdgeInsets.only(left: 20),
height: 40,
child: Text(title));
}
@override
double get maxExtent => minExtent;
@override
double get minExtent => 40;
@override
bool shouldRebuild(covariant HeaderDelegate oldDelegate) => title!=oldDelegate.title;
}
3. 穿插轴分组相关 Sliver 组件
其间 SliverConstrainedCrossAxis
和 SliverCrossAxisExpanded
用于操控滑片在穿插轴的尺度;有人可能会疑问,一般来说,穿插轴方向的尺度不便是视口尺度吗,为什么需要操控穿插轴方向的滑片尺度呢?有些场景下,咱们期望穿插轴方向能够排若干个 Sliver 滑块,一起响应滚动,特别是像宽度充裕的桌面端。
如下所示,左中右三块 SliverList 水平排布,一起滑动。这种场景在之前是很难完成的,现在有了 SliverCrossAxisGroup
组件,就能够在竖直滑动视口中,将若干个 Sliver 水平排列,作为一个滑片组。而 SliverConstrainedCrossAxis
和 SliverCrossAxisExpanded
两个组件便是用于操控滑片在穿插轴方向尺度的,所以说这三位是同一条船上的。
下滑 | 上滑 |
---|---|
SliverConstrainedCrossAxis 组件能够在穿插轴方向包容若干个 Sliver 组件。比方竖直方向滑动中,他就类似于 Row 组件,将 Sliver 孩子们水平排列。其间:
SliverConstrainedCrossAxis:指定滑片的穿插轴尺度。
SliverCrossAxisExpanded:指定滑片的穿插轴上占据的份额。
事例中需要预备三个 SliverList 的滑块,为了简略起见,这儿简略封装一个 SliverColorList 用于构建滑块组件,可指定色块色彩、条目高、条目数量等:
class SliverColorList extends StatelessWidget {
final double height;
final double fontSize;
final Color? color1;
final Color? color2;
final int count;
const SliverColorList(
{super.key,
required this.height,
required this.fontSize,
required this.count,
this.color1,
this.color2});
@override
Widget build(BuildContext context) {
return SliverList.builder(
itemBuilder: (BuildContext context, int index) {
return Container(
color: index.isEven ? color1 : color2,
height: height,
child: Center(
child: Text(
'Item ${index}',
style: TextStyle(fontSize: fontSize),
),
),
);
},
itemCount: count,
);
}
}
下面便是 SliverCrossAxisGroup
的运用方法,其实很简略,塞入 slivers 列表就行了。其间经过 SliverConstrainedCrossAxis
能够指定某个滑块在水平方向的固定尺度;也能够经过 SliverCrossAxisExpanded
指定在水平方向尺度的占份,下面 tag1 和 tag2 处经过 flex 属性指定份额 1:2, 所以右侧滑块的水平尺度是中间的两倍:
class SliverCrossAxisGroupExample extends StatelessWidget {
const SliverCrossAxisGroupExample({super.key});
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverCrossAxisGroup(
slivers: <Widget>[
SliverConstrainedCrossAxis(
maxExtent: 100,
sliver: SliverColorList(
height: 100.0,
fontSize: 24,
count: 8,
color1: Colors.amber[300],
color2: Colors.blue[300],
),
),
SliverCrossAxisExpanded(
flex: 1, // tag1
sliver: SliverColorList(
height: 80.0,
fontSize: 18,
count: 15,
color1: Colors.green[300],
color2: Colors.red[300],
),
),
SliverCrossAxisExpanded(
flex: 2, // tag2
sliver: SliverColorList(
height: 50.0,
fontSize: 20,
count: 6,
color1: Colors.purple[300],
color2: Colors.orange[300],
)),
],
),
],
);
}
}
这便是 SliverCrossAxisGroup、SliverConstrainedCrossAxis、SliverCrossAxisExpanded 三个组件的所有用法,还是十分简略和直观的。处理的场景是:
在穿插轴方向,需要摆放若干个滑块时,这些滑块能够一起滚动。
4. 装修滑块 DecoratedSliver
DecoratedSliver 其实很好了解,它便是滑动版的 DecoratedBox, 能够在滑动视口中,用于装修 Sliver 滑片。之前需要对滑片进行装修,是很难做到的,由于滑块在布局上遭到的是滑动束缚 SliverConstraints ,而不是盒束缚 BoxConstraints。现在有了 DecoratedSliver 组件,指定 decoration 装修对象即可:
其间 decoration 参数类型是 Decoration ,能够运用 BoxDecoration 完成类,增加阴影、边线、圆角、突变、色彩、图片背景等。 当然也能够自定义 Decoration 自己绘制,装修的详细运用可详见 《 【Flutter 组件集录】 DecoratedBox》 ,这儿就不赘述了。
标题 | |
---|---|
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
sliver: DecoratedSliver(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Color(0xFF111133),
blurRadius: 2,
offset: Offset(-2, -1))
],
gradient: LinearGradient(
colors: <Color>[
Color(0xFFEEEEEE),
Color(0xFF111133),
],
stops: <double>[0.1, 1.0],
),
),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text(
'张风捷特烈-$index',
style: TextStyle(fontSize: 24, color: Colors.white),
)),
),
childCount: 128),
),
),
),
到这儿,五个新的 Sliver 组件就介绍结束了,总的来说这五个都是十分有用,并且运用起来并不复杂。能够处理一些特定的滑动问题。本文的组件运用事例将会集成到 FlutterUnit 中,欢迎大家对项目多多关照。那本文就到这儿,谢谢观看~
结尾:
笔者将在 bilibli 不定期发布一些视频教程,欢迎大家能够重视和支持。另外大众号也能够重视一下,也会发布一些文章。
bilibli 账号: 张风捷特烈
大众号: 编程之王