[英]How to detect scroll position of ListView in Flutter
我正在使用ListView
小部件将项目显示为列表。 在窗口三中,查看的项目必须将中间的项目放在中间。
那么如何在滚动停止时检测ListView
的位置呢?
如何检测 ListView 滚动停止?
我使用了NotificationListener
,它是一个小部件,用于侦听在树上冒泡的通知。 然后使用ScrollEndNotification
,它表示滚动已停止。
对于滚动位置,我使用_scrollController
类型为ScrollController
。
NotificationListener(
child: ListView(
controller: _scrollController,
children: ...
),
onNotification: (t) {
if (t is ScrollEndNotification) {
print(_scrollController.position.pixels);
}
},
),
majidfathi69 的回答很好,但是您不需要在列表中添加控制器:(当您只想在滚动结束时收到通知时,请将ScrollUpdateNotification
更改为ScrollEndNotification
。)
NotificationListener<ScrollUpdateNotification>(
child: ListView(
children: ...
),
onNotification: (notification) {
//How many pixels scrolled from pervious frame
print(notification.scrollDelta);
//List scroll position
print(notification.metrics.pixels);
},
),
您还可以通过以下步骤实现此功能
import 'package:flutter/material.dart';
class YourPage extends StatefulWidget {
YourPage({Key key}) : super(key: key);
@override
_YourPageState createState() => _YourPageState();
}
class _YourPageState extends State<YourPage> {
ScrollController _scrollController;
double _scrollPosition;
_scrollListener() {
setState(() {
_scrollPosition = _scrollController.position.pixels;
});
}
@override
void initState() {
_scrollController = ScrollController();
_scrollController.addListener(_scrollListener);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text('Position $_scrollPosition pixels'),
),
body: Container(
child: ListView.builder(
controller: _scrollController,
itemCount: 200,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.mood),
title: Text('Item: $index'),
);
},
)),
);
}
}
NotificationListener
现在接受一个使代码更短的类型参数:)
NotificationListener<ScrollEndNotification>(
child: ListView(
controller: _scrollController,
children: ...
),
onNotification: (notification) {
print(_scrollController.position.pixels);
// Return true to cancel the notification bubbling. Return false (or null) to
// allow the notification to continue to be dispatched to further ancestors.
return true;
},
),
如果你想检测ListView
的滚动位置,你可以简单地使用它;
Scrollable.of(context).position.pixels
除了@seddiq-sorush 回答,你可以将当前位置与_scrollController.position.maxScrollExtent
进行比较,看看列表是否在底部
我会说您可以通过以下方式轻松检测滚动位置
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_scrollController.addListener(() {
var _currectScrollPosition = _scrollController.position.pixels;//this is the line
});
}
但是如果你要在 addListener() 中调用 setState ; 没关系,但这会导致重建整个构建(上下文)。 这对于动画来说不是一个好习惯。
我建议将您的滚动小部件分离成一个单独的 StatefulWidget ,然后通过调用获取该小部件的状态
_yourScrollableWidgetKey.currentState?.controller.addListener(() {
//code.......
setState(() {});
});
注意:设置一个 GlobalKey,并分配给您的 StatFulWidget。
final _yourScrollableWidgetKey = GlobalKey<_YourScrollAbleWidget>();
StackedPositionedAnimated(
key: _yourScrollableWidgetKey,
),
https://coflutter.com/flutter-check-if-the-listview-reaches-the-top-or-the-bottom/来源
如果有人想检测列表视图的底部,那么使用这种方式
NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
if (notification.metrics.atEdge) {
if (notification.metrics.pixels == 0) {
print('At top');
} else {
print('At bottom');
}
}
return true;
},
child: ListView.builder(itemBuilder: (BuildContext context) {
return YourItemWidget;
})
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.