Flutter:保存并恢复列表视图最后滚动位置不起作用
Flutter: Save and restore listview last scroll position not working
我需要在应用重新启动时恢复列表视图中的最后滚动位置。我正在使用 listview.builder & scroll controller 来保存和恢复偏移量,但列表视图不会滚动到上一个位置并从顶端。我什至尝试在共享首选项中保存滚动位置并在应用重启时检索但没有结果。如果有人能帮助我并让它发挥作用,我将不胜感激。谢谢
class DoubleHolder {
double value = 0.0;
}
class ListViewScreen3 extends StatefulWidget {
String itemHolder;
final DoubleHolder offset = new DoubleHolder();
ListViewScreen3({Key key, @required this.itemHolder}) : super(key: key);
double getOffsetMethod() {
return offset.value;
}
void setOffsetMethod(double val) {
offset.value = val;
}
ListViewScreenState3 createState() => new ListViewScreenState3();
}
@override
class ListViewScreenState3 extends State<ListViewScreen3> {
ScrollController _controller;
@override
void initState() {
super.initState();
getAllSavedData();
_controller = new ScrollController(
initialScrollOffset: widget.getOffsetMethod()
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
// Future.delayed(Duration(seconds: 2), () {load();});
final makeBody = Container(
decoration: BoxDecoration(
color: light_mode ? Color(0xFFFFFFFF) : Color(0xFF6D6D6D)),
child: returnListView());
}
Widget returnListview() {
return Column(
textDirection: TextDirection.rtl,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
new Expanded(
child: SizedBox(
height: 200.0,
child: new NotificationListener(
child: ListView.builder(
controller: _controller,
itemCount: ((surahcountlist.length)/2).toInt(),
itemBuilder: (context, index) {
return GestureDetector(
child: Card(
color: light_mode
? Colors.white
: Color(0xFF6D6D6D),
child: Column(
textDirection: TextDirection.rtl,
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: <Widget>[
showBSMLSV(index),
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
runAlignment: WrapAlignment.center,
textDirection: TextDirection.rtl,
spacing: 2.0,
// gap between adjacent chips
runSpacing: 5.0,
children: makeSurahListview(
surahcountlist[index].surah_no,
surahcountlist[index].ayah_no,
surahcountlist[index].count,
index)),
])));
}),
onNotification: (notification) {
if (notification is ScrollNotification) {
widget.setOffsetMethod(notification.metrics.pixels);
}}
)
))],
);
}
我有两个猜测,请检查一下,看看哪个有效。
首先我认为你需要给列表视图一些时间来构建然后跳转到你想要的位置。基本上只需在初始化滚动控制器
后在 initState 方法中添加 Future.delayed
Future.delayed(Duration(seconds:
1),(){controller.jumpto();});
其次,我认为这是因为您正在使用 listview.builder。这个小部件构建它的 children,所以如果你保持第 10 个 child 的位置,它将无法到达那里,因为它还没有构建它。我认为您需要使用 listview 并为其 children 使用 List.generate()
我需要在应用重新启动时恢复列表视图中的最后滚动位置。我正在使用 listview.builder & scroll controller 来保存和恢复偏移量,但列表视图不会滚动到上一个位置并从顶端。我什至尝试在共享首选项中保存滚动位置并在应用重启时检索但没有结果。如果有人能帮助我并让它发挥作用,我将不胜感激。谢谢
class DoubleHolder {
double value = 0.0;
}
class ListViewScreen3 extends StatefulWidget {
String itemHolder;
final DoubleHolder offset = new DoubleHolder();
ListViewScreen3({Key key, @required this.itemHolder}) : super(key: key);
double getOffsetMethod() {
return offset.value;
}
void setOffsetMethod(double val) {
offset.value = val;
}
ListViewScreenState3 createState() => new ListViewScreenState3();
}
@override
class ListViewScreenState3 extends State<ListViewScreen3> {
ScrollController _controller;
@override
void initState() {
super.initState();
getAllSavedData();
_controller = new ScrollController(
initialScrollOffset: widget.getOffsetMethod()
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
// Future.delayed(Duration(seconds: 2), () {load();});
final makeBody = Container(
decoration: BoxDecoration(
color: light_mode ? Color(0xFFFFFFFF) : Color(0xFF6D6D6D)),
child: returnListView());
}
Widget returnListview() {
return Column(
textDirection: TextDirection.rtl,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
new Expanded(
child: SizedBox(
height: 200.0,
child: new NotificationListener(
child: ListView.builder(
controller: _controller,
itemCount: ((surahcountlist.length)/2).toInt(),
itemBuilder: (context, index) {
return GestureDetector(
child: Card(
color: light_mode
? Colors.white
: Color(0xFF6D6D6D),
child: Column(
textDirection: TextDirection.rtl,
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: <Widget>[
showBSMLSV(index),
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
runAlignment: WrapAlignment.center,
textDirection: TextDirection.rtl,
spacing: 2.0,
// gap between adjacent chips
runSpacing: 5.0,
children: makeSurahListview(
surahcountlist[index].surah_no,
surahcountlist[index].ayah_no,
surahcountlist[index].count,
index)),
])));
}),
onNotification: (notification) {
if (notification is ScrollNotification) {
widget.setOffsetMethod(notification.metrics.pixels);
}}
)
))],
);
}
我有两个猜测,请检查一下,看看哪个有效。
首先我认为你需要给列表视图一些时间来构建然后跳转到你想要的位置。基本上只需在初始化滚动控制器
后在 initState 方法中添加 Future.delayedFuture.delayed(Duration(seconds:
1),(){controller.jumpto();});
其次,我认为这是因为您正在使用 listview.builder。这个小部件构建它的 children,所以如果你保持第 10 个 child 的位置,它将无法到达那里,因为它还没有构建它。我认为您需要使用 listview 并为其 children 使用 List.generate()