我有一个水平的ListView。在用户松开手指并且ListView减速停止后,我希望视图将最中间的小部件直接放置在ListView的中心。
为此,我有一个NotificationListener:
child: NotificationListener<ScrollNotification>(
onNotification: onNotification,
child: ListView.builder(
controller: _controller,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 30,
itemBuilder: (BuildContext context, int index) {
return _buildProfileIcon(context, index);
},
),
),
其onNotifcation方法检查滚动是否结束:
bool onNotification(ScrollNotification scrollNotification) {
if (scrollNotification is ScrollEndNotification) {
_centerElement(findCenterElement());
}
return null;
}
为了找到和居中已经最靠近中心的元素:
int findCenterElement() {
double offset = _controller.offset + 2*profileWidth;
int centerishElement = offset < profileWidth
? 0
: ((offset - profileWidth) / profileWidth).ceil();
return centerishElement;
}
void _centerElement(int index) {
RenderBox renderBox = context.findRenderObject();
double viewWidth = renderBox.size.width;
_controller.animateTo(
(profileWidth*index - viewWidth/2 + profileWidth/2),
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
}
我在这些配置文件图标窗口小部件(此ListView列出的窗口小部件)上的GestureDetectors onTap()方法调用了相同的centerElement(int index)方法,它使元素居中。设置断点实际上表明,当onNotification作为ScrollEndNotification触发时,将调用_centerElement(),并且其中的_controller.animateTo()方法也会被调用。但是对于NotificationListener事件,animateTo()实际上不会移动列表。
答案 0 :(得分:0)
滚动没有尽头,所以不能animateTo
在某个地方,
if (scrollNotification is UserScrollNotification && scrollNotification.direction == ScrollDirection.idle) {
scrollcontrol.animateTo(100, duration: Duration(milliseconds: 200), curve: Curves.ease);
}