Flutter - ListView inside on a TabBarView loses its scroll position

前端 未结 7 1528
误落风尘
误落风尘 2021-01-30 11:07

I have a very simple Flutter app with a TabBarView with two views (Tab 1 and Tab 2), one of them (Tab 1) has

相关标签:
7条回答
  • 2021-01-30 11:16

    If you give each TabBarView a PageStorageKey the scroll offset will be saved. See more info about PageStorageKey here.

    0 讨论(0)
  • 2021-01-30 11:16

    Output:


    Code:

    @override
    Widget build(BuildContext context) {
      return DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: AppBar(
            title: Text("PageStorageKey"),
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.looks_one), text: "List1"),
                Tab(icon: Icon(Icons.looks_two), text: "List2"),
              ],
            ),
          ),
          body: TabBarView(
            children: [
              _buildList(key: "key1", string: "List1: "),
              _buildList(key: "key2", string: "List2: "),
            ],
          ),
        ),
      );
    }
    
    Widget _buildList({String key, String string}) {
      return ListView.builder(
        key: PageStorageKey(key),
        itemBuilder: (_, i) => ListTile(title: Text("${string} ${i}")),
      );
    }
    
    0 讨论(0)
  • 2021-01-30 11:17

    Is there a way to execute Widget build(BuildContext context) method only once...

    Imho, idea of flutter is to be ready for rebuilding always. It should be cheap. If you have some expensive actions, you can use State to "cache" results. E.g. you can do network request in initState and via setState rebuild when receive response. For tabs, you can prepare and save data in parent widget. You can find more info in flutter tutorial about managing state

    0 讨论(0)
  • 2021-01-30 11:25

    To be more specific, you can use PageStorageKey with any scrollable view to keep the scrolling position, e.g.:

    new ListView.builder(key: new PageStorageKey('myListView'), ...)
    
    0 讨论(0)
  • 2021-01-30 11:28

    0 讨论(0)
  • 2021-01-30 11:29

    Can't add a comment, so left it as answer.

    If you using PageStorageKey, have a lot of items in the ListView, scroll down plenty items and have lag on tab switch, the solution is to provide itemExtent to ListView.

    As I understand, without itemExtent ListView don't know which items immediately show, because using PageStorageKey cashed only position in pixels, and ListView need calculate height of all items scrolled from top. In another hand, with itemExtent ListView can easily calculate item to show, for example: index = cashedPositionInPixels / itemExtent.

    0 讨论(0)
提交回复
热议问题