Flutter:获取 ListView/GridView 中的当前滚动偏移量
本文将向您展示如何在 ListView 或 Flutter 中的其他可滚动小部件(如 GridView、SingleSchildScrollView、CustomScrollView 等)中获取当前滚动偏移量(表示到顶部的距离,以像素为单位)。我们将发现机制然后研究在实践中应用该机制的完整示例。
重点是什么?
要在 Flutter 中计算可滚动小部件中的滚动偏移量,首先要做的是初始化一个ScrollController实例:
final ScrollController _controller = ScrollController();
然后将此控制器连接到可滚动小部件:
ListView.builder(
// attact the controller
controller: _controller,
/* ... */
),
现在您可以添加一个侦听器并获得如下结果:
@override
void initState() {
_controller.addListener(() {
// print out the scroll offset
print(_controller.offset);
});
super.initState();
}
如果列表视图滚动到其末尾,则滚动偏移量将等于或大于以下值:
controller.position.maxScrollExtent
为了更好地理解,请参阅下面的完整示例。
例子
应用预览
我们要制作的演示应用程序包含一个应用程序栏、一个列表视图(呈现很多项目)和一个底栏。滚动偏移量将显示在底部栏中。底栏的背景颜色取决于滚动偏移量:
- 如果滚动偏移量等于或小于零,则背景为绿色(滚动偏移量可能为负数)
- 如果滚动到列表视图的末尾,背景颜色将为红色。此外,将出现一个带有“您已到达列表视图末尾”消息的快餐栏
- 在其余情况下,底栏的背景为蓝色
以下是它的工作原理:
此示例旨在演示如何检索可滚动小部件中的滚动位置并检测它是否滚动到底部/顶部。
编码
main.dart中的完整源代码(在注释中有解释):
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'KindaCode.com',
theme: ThemeData(
primarySwatch: Colors.amber,
),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
// Generate dummy data to fill the list view
final List _items = List.generate(50, (index) => 'Item $index');
// The controller that is assigned to the list view
final ScrollController _controller = ScrollController();
// The scroll offset
double _scrollOffset = 0;
// The maximum scroll offset
// In other words, this means the user has reached the bottom of the list view
double? _maxOffset;
@override
void initState() {
_controller.addListener(() {
_maxOffset = _controller.position.maxScrollExtent;
setState(() {
_scrollOffset = _controller.offset;
if (_maxOffset != null && _scrollOffset >= _maxOffset!) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('You have reached the end of the list view')));
} else {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
}
});
});
super.initState();
}
// Discards any resources used by the scroll controller object
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('KindaCode.com')),
// implement the list view
body: ListView.builder(
// attact the controller
controller: _controller,
itemBuilder: ((context, index) => Card(
key: ValueKey(_items[index]),
margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
elevation: 6,
color: Colors.amber.shade100,
child: ListTile(
title: Text(_items[index]),
),
)),
itemCount: _items.length,
),
// display the scroll offset
bottomNavigationBar: BottomAppBar(
elevation: 6,
// set the background color of the bottom bar based on the the current offset position
// if at the top: green
// if at the bottom: red
// otherwise: blue
color: _scrollOffset <= 0
? Colors.green
: _maxOffset != null && _scrollOffset >= _maxOffset!
? Colors.red
: Colors.blue,
child: Padding(
padding: const EdgeInsets.only(top: 20, left: 20),
child: Text(
"Offset: ${_scrollOffset.toString()}",
style: const TextStyle(
fontSize: 21, color: Colors.white, fontWeight: FontWeight.bold),
),
),
),
);
}
}
结论
您已经学习了如何在 Flutter 的可滚动小部件中找到滚动偏移位置。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站。本站所有源码与软件均为原作者提供,仅供学习和研究使用。如您对本站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。