这段代码通过合理运用 Flutter 的各种组件、控制器以及覆盖层等相关技术,实现了根据页面滚动情况动态显示和隐藏悬浮按钮,并实现了点击悬浮按钮使页面滚动回顶部的功能。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ScrollController _scrollController = ScrollController();
OverlayEntry? _floatingButtonOverlayEntry;
void initState() {
super.initState();
_scrollController.addListener(_scrollListener);
}
void dispose() {
_scrollController.removeListener(_scrollListener);
_scrollController.dispose();
super.dispose();
}
void _scrollListener() {
if (_scrollController.offset > 100 && _floatingButtonOverlayEntry == null) {
// 显示悬浮按钮
_showFloatingButton();
} else if (_scrollController.offset <= 100 &&
_floatingButtonOverlayEntry != null) {
// 隐藏悬浮按钮
_hideFloatingButton();
}
}
void _showFloatingButton() {
_floatingButtonOverlayEntry = OverlayEntry(
builder: (context) {
return Positioned(
right: 20.0,
bottom: 20.0,
child: FloatingActionButton(
onPressed: _scrollToTop,
child: Icon(Icons.arrow_upward),
),
);
},
);
Overlay.of(context)!.insert(_floatingButtonOverlayEntry!);
}
void _hideFloatingButton() {
_floatingButtonOverlayEntry!.remove();
_floatingButtonOverlayEntry = null;
}
void _scrollToTop() {
_scrollController.animateTo(
0,
duration: Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Floating Button Example')),
body: NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
// 可以在这里处理滚动通知
return true;
},
child: ListView.builder(
controller: _scrollController,
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
),
),
);
}
}
以下是分析内容:
-
整体功能
实现了一个页面功能,当页面内容向下滚动超过 100 像素时,会在页面右下角显示一个悬浮的向上箭头按钮,点击该按钮可使页面快速滚动回到顶部;当页面滚动回到距离顶部 100 像素以内时,悬浮按钮会隐藏。 -
导入库
通过 import ‘package:flutter/material.dart’; 导入 Flutter 核心库,用于获取构建应用所需的 UI 组件、样式及相关功能等。 -
应用入口点(main 函数)
main 函数作为 Flutter 应用入口,调用 runApp 并传入 MyApp 类实例来启动应用。 -
MyApp 类
MyApp 继承自 StatelessWidget,为无状态组件,其 build 方法返回 MaterialApp 实例并指定首页为 MyHomePage 类实例,UI 创建后不因内部状态改变重新渲染。 -
MyHomePage 类
继承关系与状态管理:
MyHomePage 继承自 StatefulWidget,表明页面 UI 可能随内部状态变化重新渲染,通过 createState 方法创建并返回对应的 _MyHomePageState 实例管理页面状态。
_MyHomePageState 类相关操作:
状态管理相关变量和控制器:
定义一个 ScrollController,用于控制页面滚动相关操作,比如获取当前滚动偏移量等。
一个 OverlayEntry 类型变量,用于管理悬浮按钮在页面上的显示和隐藏状态,初始值为 null。
生命周期方法:
在页面初始化时调用的方法中,给 ScrollController 添加滚动监听器,以便在滚动事件发生时处理。
在页面销毁时调用的方法会移除之前添加给 ScrollController 的滚动监听器,并释放其占用的资源。
滚动监听器方法:
根据 ScrollController 的当前滚动偏移量以及 OverlayEntry 类型变量的状态来决定是显示还是隐藏悬浮按钮。当滚动偏移量大于 100 像素且该变量为 null(悬浮按钮未显示)时,调用相关方法显示悬浮按钮;当滚动偏移量小于等于 100 像素且该变量不为 null(悬浮按钮已显示)时,调用相关方法隐藏悬浮按钮。
显示悬浮按钮方法:
先创建一个 OverlayEntry,其构建函数返回一个组件用于将悬浮操作按钮定位在页面右下角,设置按钮图标为向上箭头,点击可调用滚动到顶部的方法。
然后将创建好的 OverlayEntry 插入到页面覆盖层中,使悬浮按钮显示在页面上。
隐藏悬浮按钮方法:
直接调用 OverlayEntry 的 remove 方法移除之前插入的 OverlayEntry,并将该变量重置为 null,使悬浮按钮从页面消失。
滚动到顶部方法:
使用 ScrollController 的相关方法,让页面滚动条在 500 毫秒内以特定曲线动画效果滚动到顶部(偏移量为 0)。
构建 UI 方法:
返回一个 Scaffold 组件,包含 appBar(设置标题)和 body(主体内容)部分。
appBar 标题设为 Floating Button Example。
body 部分用 NotificationListener 来监听滚动通知,其内部包裹着一个 ListView.builder,通过相关控制器控制滚动,设置列表项目数量,每个项目通过相关构建方法构建为特定格式显示。