Flutter滑动定位插件sliver_snap的使用
Flutter滑动定位插件sliver_snap的使用
Sliver Snap 简介
🚀 Sliver Snap 是一个Flutter包,它简化了在应用程序中添加可折叠和可展开的应用栏(AppBar)的过程。它提供了对用户滚动无缝响应的平滑过渡,并且当用户停止滚动时会自动调整到适当的状态。💻 它高度可定制,提供友好的用户体验。告别手动实现,使您的Flutter应用程序更加交互式和直观。
Platform Pub Package License: MIT
预览
basic | Performance |
---|---|
安装
1. Depend on it
将以下内容添加到您的 pubspec.yaml
文件:
dependencies:
sliver_snap: ^2.0.0
或者您可以通过命令行添加最新版本:
flutter pub add sliver_snap
2. Install it
通过命令行安装包:
$ flutter pub get
3. Import it
现在可以在您的 Dart 代码中使用:
import 'package:sliver_snap/sliver_snap.dart';
基本用法
SliverSnap(
onCollapseStateChanged: (isCollapsed, scrollingOffset, maxExtent) {},
collapsedBackgroundColor: Colors.black,
expandedBackgroundColor: Colors.transparent,
backdropWidget: Image.network(
"https://picsum.photos/800/1200",
fit: BoxFit.cover,
),
bottom: const PreferredSize(
preferredSize: Size.fromHeight(50),
child: Icon(
Icons.directions_boat,
color: Colors.blue,
size: 45,
),
),
expandedContentHeight: 400,
expandedContent: const Center(
child: Icon(
Icons.ac_unit_sharp,
color: Colors.amber,
size: 70,
),
),
collapsedContent: const Icon(Icons.car_crash, color: Colors.green, size: 45),
body: const Material(
elevation: 7,
child: Placeholder(),
),
);
属性说明
Property | Type | Default Value | Description |
---|---|---|---|
expandedContent | Widget | N/A | 展开时显示的内容。是必需属性。 |
collapsedContent | Widget | N/A | 收缩时显示的内容。是必需属性。 |
body | Widget | N/A | 应用栏下方显示的内容。是必需属性。 |
pinned | boolean | true | 应用栏是否固定在滚动视图顶部。更多信息请参阅 Flutter Docs。 |
collapsedBarHeight | double | 60.0 | 收缩内容的高度。 |
animationDuration | Duration | 300 milliseconds | 滚动动画的持续时间。 |
animationCurve | Curve | Curves.easeInOut | 滚动动画的曲线。 |
snap | boolean | false | 应用栏在滚动时的行为方式。更多信息请参阅 Flutter Docs。 |
floating | boolean | false | 应用栏在用户向应用栏滚动时是否立即可见。更多信息请参阅 Flutter Docs。 |
stretch | boolean | false | 应用栏是否拉伸以填充过滚动区域。更多信息请参阅 Flutter Docs。 |
expandedContentHeight | double? | N/A | 展开内容的高度。 |
bottom | PreferredSizeWidget? | N/A | 显示在应用栏底部的小部件,例如 TabBar 。该小部件必须实现 PreferredSizeWidget 。 |
automaticallyImplyLeading | bool? | false | 控制 AppBar 的 leading 小部件。当设置为 true 时,框架将自动添加 leading 小部件;当设置为 false 时,不会自动添加。更多信息请参阅 Flutter Docs。 |
leading | Widget? | N/A | 在 expandedContent 和 collapsedContent 开始处的领先小部件,通常是 Icon 或 IconButton 。也可以是 BackButton 。 |
actions | List<Widget> | N/A | 在 collapsedContent 小部件之后显示的一排操作小部件。 |
backdropWidget | Widget? | N/A | 应用栏下方显示的内容。通常只是页面内容。 |
expandedBackgroundColor | Color? | N/A | expandedContent 小部件的背景颜色。 |
collapsedBackgroundColor | Color? | N/A | collapsedContent 小部件的背景颜色。 |
scrollController | ScrollController? | N/A | 可以传递自己的 scrollController 以进一步自定义应用栏。 |
scrollBehavior | ScrollBehaviour? | N/A | 滚动小部件的行为,可以是 Material 或 Cupertino 滚动行为。 |
onCollapseStateChanged | CollapsingStateCallback? | N/A | 当应用栏折叠或展开时触发的回调函数,可用于自定义动画和行为。 |
elevation | double | 0.0 | 应用栏的阴影高度。 |
forceElevated | bool | false | 是否在内容未滚动到应用栏下方时也显示与 elevation 相匹配的阴影。默认为 false ,即只有在应用栏显示在滚动内容上方时才应用阴影。 |
额外组件
1. Collapsed AppBar Content widget
用于创建自定义 collapsedContent
小部件。具有以下属性:
- leading:
collapsedContent
应用栏的领先小部件。 - title:
collapsedContent
应用栏中间的小部件。 - trailing:
collapsedContent
应用栏最右侧的小部件。
CollapsedAppBarContent(
leading: const Text('Leading Widget'),
title: const Text('title'),
trailing: SizedBox(
height: 40,
child: Image.network(
'https://picsum.photos/800/1200',
fit: BoxFit.cover,
),
),
),
2. Expanded Content widget
用于创建自定义 expanded
小部件。具有以下属性:
- leading:
expandedContent
应用栏的领先小部件。
ExpandedContent(
leading: const Text('Leading Widget'),
child: const Text('Expanded Content'),
);
示例代码
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:sliver_snap/sliver_snap.dart';
void main() async {
runApp(const MyApp());
if (Platform.isAndroid) {
await FlutterDisplayMode.setHighRefreshRate();
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: [
SliverSnap(
onCollapseStateChanged: (isCollapsed, scrollingOffset, maxExtent) {
// 处理状态变化的逻辑
},
collapsedBackgroundColor: Colors.black,
expandedBackgroundColor: Colors.transparent,
backdropWidget: Image.network(
"https://picsum.photos/800/1200",
fit: BoxFit.cover,
),
bottom: const PreferredSize(
preferredSize: Size.fromHeight(50),
child: Icon(
Icons.directions_boat,
color: Colors.blue,
size: 45,
),
),
expandedContentHeight: 400,
expandedContent: const Center(
child: Icon(
Icons.ac_unit_sharp,
color: Colors.amber,
size: 70,
),
),
collapsedContent: const Icon(Icons.car_crash, color: Colors.green, size: 45),
body: const Material(
elevation: 7,
child: Placeholder(),
),
),
],
),
),
);
}
}
更多信息
更多使用信息,请参考 示例代码。
如果您遇到任何问题,请随时在 GitHub Issues 中提交问题或功能请求。欢迎提交 Pull Request。
更多关于Flutter滑动定位插件sliver_snap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter滑动定位插件sliver_snap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,sliver_snap
并不是一个官方的插件,但听起来它类似于一个用于 Sliver 列表项定位与吸附的库。如果你正在寻找一个插件来实现类似的效果,比如让 Sliver 列表中的某个项在用户滚动时能够吸附到屏幕边缘,那么你可以考虑使用 flutter_sticky_headers
或者通过自定义 Sliver 组件来实现。
不过,为了说明如何在 Flutter 中实现一个基本的滑动定位功能,我们可以使用 Flutter 自带的 SliverList
和 ScrollController
来创建一个简单的示例,这个示例将展示如何定位到列表中的特定项。请注意,这个示例不会直接提供“吸附”效果,但它是实现更复杂功能的基础。
以下是一个基本的 Flutter 应用示例,它展示了如何使用 ScrollController
跳转到 SliverList
中的特定项:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SliverSnap Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ScrollController _scrollController = ScrollController();
final List<String> _items = List.generate(100, (index) => 'Item $index');
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
void _scrollToIndex(int index) {
final SliverGeometry geometry = _getSliverGeometryAtIndex(index);
if (geometry != null) {
final double scrollOffset = geometry.paintExtent - geometry.scrollOffset;
_scrollController.animateTo(
scrollOffset,
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
}
SliverGeometry? _getSliverGeometryAtIndex(int index) {
final RenderSliver? sliver = _sliverContextAtIndex(index)?.findRenderObject() as RenderSliver?;
if (sliver != null) {
final SliverConstraints constraints = sliver.constraints;
final SliverGeometry geometry = sliver.getGeometryForChildIndex(index);
return geometry;
}
return null;
}
BuildContext? _sliverContextAtIndex(int index) {
final List<SliverPersistentHeaderDelegate?>? headers = <SliverPersistentHeaderDelegate?>[]; // Not used in this example but can be extended for sticky headers
final SliverMultiBoxAdaptorElement? element = _findSliverMultiBoxAdaptorElement(context);
if (element != null) {
final int firstIndex = element.firstChild!.index;
final int lastIndex = element.lastChild!.index;
if (index >= firstIndex && index <= lastIndex) {
return element.childAfter(element.indexOf(element.firstChild!) + index - firstIndex)!;
}
}
return null;
}
SliverMultiBoxAdaptorElement? _findSliverMultiBoxAdaptorElement(BuildContext context) {
Element? element = context.findAncestorElementThatMatchesPredicate(
(Element candidate) => candidate is SliverMultiBoxAdaptorElement,
);
return element as SliverMultiBoxAdaptorElement?;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SliverSnap Example'),
),
body: CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return ListTile(
title: Text(_items[index]),
);
},
childCount: _items.length,
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () => _scrollToIndex(50), // Scroll to the 50th item
tooltip: 'Scroll to Item 50',
child: Icon(Icons.arrow_downward),
),
);
}
}
注意:
_scrollToIndex
方法尝试滚动到指定索引的项,但它依赖于_getSliverGeometryAtIndex
和_sliverContextAtIndex
方法来获取 Sliver 项的几何信息。这些方法在这个简单示例中可能不会总是有效,特别是在复杂的 Sliver 布局中。- 对于更复杂的“吸附”效果,你可能需要更深入地了解 Flutter 的 Sliver 架构,并可能需要自定义 Sliver 组件或使用第三方库。
- 在生产环境中,建议进行更全面的错误处理和边界情况检查。
如果你确实在寻找一个名为 sliver_snap
的特定插件,请确保你查找的是正确的包名或在 Flutter 社区中询问以获取更多信息。