Flutter 状态更改时重置颤振自定义滚动视图
我正在构建一个垂直滚动日历,我已经将我的日子实现为多个Flutter 状态更改时重置颤振自定义滚动视图,flutter,dart,flutter-sliver,Flutter,Dart,Flutter Sliver,我正在构建一个垂直滚动日历,我已经将我的日子实现为多个SliverLists,这样我就可以专注于某一天,而在过去和未来仍然有日子 问题是,当focusDate通过父级中的状态更改而更改时,列表会正确更新日期,但保持其滚动位置。例如,如果我被滚动到列表的顶部,则更改focusDatedays更新,但我仍然位于列表的顶部 我希望在focusDate更改时完全替换列表(而不仅仅是日期)。从日期选择器中拾取日期时会发生这种情况。因此,无论如何都需要获取新数据,并且可以创建一个新的CustomScroll
SliverList
s,这样我就可以专注于某一天,而在过去和未来仍然有日子
问题是,当focusDate
通过父级中的状态更改而更改时,列表会正确更新日期,但保持其滚动位置。例如,如果我被滚动到列表的顶部,则更改focusDate
days更新,但我仍然位于列表的顶部
我希望在focusDate
更改时完全替换列表(而不仅仅是日期)。从日期选择器中拾取日期时会发生这种情况。因此,无论如何都需要获取新数据,并且可以创建一个新的CustomScrollView
,并将其集中在正确的日期
import 'package:flutter/material.dart';
import 'day.dart';
class DaysManager extends StatelessWidget {
List<Day> days;
DaysManager({DateTime focusDate}) {
final DateTime startDate = focusDate.subtract(Duration(days: 30));
days = List.generate(61, (int index) {
return Day(
date: startDate.add(Duration(days: index)),
);
});
}
@override
Widget build(BuildContext context) {
return _buildScrollView();
}
CustomScrollView _buildScrollView() {
final focusKey = ValueKey('focus');
return CustomScrollView(
center: focusKey,
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate(
days.sublist(0, 31).reversed.toList(),
),
),
SliverList(
key: focusKey,
delegate: SliverChildListDelegate(
days.sublist(31, 32),
),
),
SliverList(
delegate: SliverChildListDelegate(
days.sublist(32),
),
),
],
);
}
}
导入“包装:颤振/材料.省道”;
输入“day.dart”;
类DaysManager扩展了无状态小部件{
列出日期;
DaysManager({DateTime focusDate}){
最终日期时间开始日期=焦点日期减去(持续时间:30天);
天数=列表生成(61,(整数索引){
回归日(
日期:startDate.add(持续时间(天数:索引)),
);
});
}
@凌驾
小部件构建(构建上下文){
返回_buildScrollView();
}
CustomScrollView\u buildScrollView(){
最终焦点键=值键(“焦点”);
返回自定义滚动视图(
中心:focusKey,
条子:[
银表(
委托:SliverChildListDelegate(
days.sublist(0,31).reversed.toList(),
),
),
银表(
键:focusKey,
委托:SliverChildListDelegate(
天。子列表(31,32),
),
),
银表(
委托:SliverChildListDelegate(
天。子列表(32),
),
),
],
);
}
}
您可以向CustomListView添加ScrollController。当您设置状态时,请使用控制器将动画设置为您刚才选择的位置
ScrollController有一个方法:
Future<Void> animateTo(
double offset, {
@required Duration duration,
@required Curve curve,
})
未来动画(
双偏移{
@所需的持续时间,
@要求的曲线,
})
其中“偏移”是要设置动画的位置 您可以向CustomListView添加ScrollController。当您设置状态时,请使用控制器将动画设置为您刚才选择的位置
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = new ScrollController();
}
@override
Widget build(BuildContext context) {
return ListView.builder(itemBuilder: (context, index){
return FlatButton(onPressed: (){
_scrollController.animateTo(index*(YOUR_VIEW_HEIGHT), duration: new Duration(seconds: 2), curve: Curves.ease);
}, child: Text("Item $index"));
}, controller: _scrollController,);
}
ScrollController有一个方法:
Future<Void> animateTo(
double offset, {
@required Duration duration,
@required Curve curve,
})
未来动画(
双偏移{
@所需的持续时间,
@要求的曲线,
})
其中“偏移”是要设置动画的位置 我看到一些引用,但我不确定控制器方法应该放在哪里。setState是从父类调用的。我正在创建列表,但是在创建和返回之间,我将在哪里调用
animateTo
?还有,为什么我不能创建一个新列表?当日子一天天过去,一个卷轴出现的时候,看起来会很糟糕。我只想让它完全重新初始化。将控制器声明为类变量,然后在CustomScrollView中通过名为“controller”的参数传递控制器。更新列表后,如果在该方法中设置state,请使用控制器对象调用animateTo方法。如果类DaysManager是无状态的,请使用该方法。我相信您正在StatefulWidget中使用它,您在其中调用set state。调用setState时,DaysManager应该使用新数据而不是旧数据重建。你能展示一些你想要达到的目标的截图吗?这是完全正确的,它会用新的数据重建。但它保持其滚动位置。就像在中一样,它正在替换数据,但没有重置滚动。我看到了一些引用,但我不确定控制器方法应该放在哪里。setState是从父类调用的。我正在创建列表,但是在创建和返回之间,我将在哪里调用animateTo
?还有,为什么我不能创建一个新列表?当日子一天天过去,一个卷轴出现的时候,看起来会很糟糕。我只想让它完全重新初始化。将控制器声明为类变量,然后在CustomScrollView中通过名为“controller”的参数传递控制器。更新列表后,如果在该方法中设置state,请使用控制器对象调用animateTo方法。如果类DaysManager是无状态的,请使用该方法。我相信您正在StatefulWidget中使用它,您在其中调用set state。调用setState时,DaysManager应该使用新数据而不是旧数据重建。你能展示一些你想要达到的目标的截图吗?这是完全正确的,它会用新的数据重建。但它保持其滚动位置。就像在中一样,它正在替换数据,但没有重置滚动。我不需要按钮。我正在寻找一种方法,使列表在重建时将其滚动位置重置为SliverList键。@WillLuce Button仅供参考。您的视图将位于Button的位置。我不需要按钮。我正在寻找一种方法,使列表在重建时将其滚动位置重置为SliverList键。@WillLuce Button仅供参考,您的视图将位于按钮的位置。
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = new ScrollController();
}
@override
Widget build(BuildContext context) {
return ListView.builder(itemBuilder: (context, index){
return FlatButton(onPressed: (){
_scrollController.animateTo(index*(YOUR_VIEW_HEIGHT), duration: new Duration(seconds: 2), curve: Curves.ease);
}, child: Text("Item $index"));
}, controller: _scrollController,);
}