flutter TabBarViewでListViewを使う

https://qiita.com/Dreamwalker/items/cc19bb4f8b7068ae0fd3

この辺りを参考にタブバーを試していたが、タブを切り替えるたびにTabBarViewのchildrenにセットしたWidgetがinitStateされてしまってListViewが毎回作られてしまった。DefaultTabController使って、StatefulWidgetにはAutomaticKeepAliveClientMixinを適用させてbool get wantKeepAlive => trueするといいらしい。

import 'package:flutter/material.dart';
import 'dart:async';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: TabBarDemo(),
    );
  }
}

class TabBarDemo extends StatelessWidget {

  final List<Tab> myTabs = <Tab>[
    Tab(text: 'LEFT'),
    Tab(text: 'RIGHT'),
  ];

  final List<_MyContent> myContents = <_MyContent>[
    _MyContent(),
    _MyContent(),
  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: myTabs.length,
      child: Scaffold(
        appBar: AppBar(
          title: Text("TabBarSample"),
          bottom: TabBar(tabs: myTabs),
        ),
        body: TabBarView(children: myContents),
      ),
    );
  }
}

class _MyContent extends StatefulWidget {

  _MyContentState _state = _MyContentState();

  @override
  State<StatefulWidget> createState() {
    return _state;
  }
}

class _MyContentState extends State<_MyContent> with AutomaticKeepAliveClientMixin {

  List<String> items = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: RefreshIndicator(
        child: ListView.builder(
          itemBuilder: (context, index) {
            if (index == items.length) {
              _load();
              return Center(child: CircularProgressIndicator());
            } else if (items.length < index) {
              return null;
            } else {
              return Container(
                child: ListTile(title: Text(items[index])),
              );
            }
          },
        ),
        onRefresh: refresh,
      )
    );
  }

  void _load() async {
    await new Future.delayed(const Duration(seconds: 1));
    setState(() {
      var s = items.length;
      for (var i = 0; i < 20; i++) {
        items.add("アイテム${s + i}");
      }
    });
  }

  Future<void> refresh() {
    return Future.sync(() {
      setState(() {
        items.clear();
        _load();
      });
    });
  }

  @override
  bool get wantKeepAlive => true;
}

以上です