当前位置:   article > 正文

Flutter ListView保留滚动位置之优化之路_flutter列表更改某一条后页面刷新但保持滚动条位置

flutter列表更改某一条后页面刷新但保持滚动条位置

        起初,采用 TabBarView + ListView 结合 TabController 的方式实现了三页列表展示。但是,切换 TabBarView 的时候,每一页需要重新绘制,导致 ListView 无法保留上次所在位置。为了解决这个问题,通过 ScrollController 的 scrollController.position.pixels 记录 ListView 停留位置,等到切换回来之时,延时100毫秒,调用 scrollController.jumpTo(value) 滚动到该位置。当然,这种方式实现没有问题,不过体验不会太好,明显可见滚动全过程。来回切换,会感觉眼花缭乱。而且三个 TabBarView ,每一个 TabBarView 的ListView 都需要记录停留位置,需要三个 ScrollController ,感觉复杂了点。

        从网上了解到,PageView 类似 Android 的 ViewPager,它可以做到页面不重绘,在此记录一下。大致原理就是,PageView 的子 Widget 必须 混入 AutomaticKeepAliveClientMixin, 同时 wantKeepAlive 返回 true ,这是官方推荐做法。切换页面时,通过 PageController 控制 PageView 显示的当前页。这样是不会重绘的,所以 ListView 展示的数据不会刷新,滚动位置也不会改变。

完整demo如下:

  1. class BgWidget extends StatefulWidget {
  2. @override
  3. State<StatefulWidget> createState() {
  4. // TODO: implement createState
  5. return _BgWidget();
  6. }
  7. }
  1. class _BgWidget extends State<BgWidget> {
  2. PageController pageController;
  3. @override
  4. void initState() {
  5. super.initState();
  6. pageController = PageController(initialPage: 0, keepPage: true);
  7. }
  8. @override
  9. void dispose() {
  10. pageController.dispose();
  11. super.dispose();
  12. }
  13. @override
  14. Widget build(BuildContext context) {
  15. return Scaffold(
  16. appBar: AppBar(
  17. title: Text('PageView'),
  18. ),
  19. body: _createBody(),
  20. );
  21. }
  22. _createBody() {
  23. return Column(
  24. children: <Widget>[
  25. _createTab(),
  26. Expanded(child: PageView(
  27. scrollDirection: Axis.horizontal,
  28. controller: pageController,
  29. physics: NeverScrollableScrollPhysics(),
  30. onPageChanged: (page) {
  31. print('page = $page');
  32. },
  33. children: <Widget>[PageListView(), PageListView(), PageListView()],
  34. ))
  35. ],
  36. );
  37. }
  38. ///类似tab
  39. _createTab(){
  40. return Row(
  41. mainAxisSize: MainAxisSize.min,
  42. children: <Widget>[
  43. Expanded(child: RaisedButton(onPressed: (){
  44. setState(() {
  45. pageController.jumpToPage(0);
  46. });
  47. },child: Text('第一页'),),),
  48. Expanded(child: RaisedButton(onPressed: (){
  49. setState(() {
  50. pageController.jumpToPage(1);
  51. });
  52. },child: Text('第二页'),),),
  53. Expanded(child: RaisedButton(onPressed: (){
  54. setState(() {
  55. pageController.jumpToPage(2);
  56. });
  57. },child: Text('第三页'),),),
  58. ],
  59. );
  60. }
  61. }
  1. ///PageView子widget
  2. class PageListView extends StatefulWidget {
  3. @override
  4. State<StatefulWidget> createState() {
  5. // TODO: implement createState
  6. return _PageListView();
  7. }
  8. }
  1. class _PageListView extends State<PageListView>
  2. with AutomaticKeepAliveClientMixin {
  3. @override
  4. Widget build(BuildContext context) {
  5. super.build(context);
  6. return ListView.builder(
  7. padding: EdgeInsets.only(bottom: 10),
  8. itemCount: 100,
  9. itemExtent: 40,
  10. shrinkWrap: true,
  11. itemBuilder: (BuildContext context, int index) {
  12. return Container(
  13. color: Colors.black12,
  14. child: Text(' 这是第 $index 行'),
  15. );
  16. });
  17. }
  18. @override
  19. // TODO: implement wantKeepAlive
  20. bool get wantKeepAlive => true;
  21. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/341748
推荐阅读
相关标签
  

闽ICP备14008679号