Flutter错误:“ indexOf(child)> index”:不正确。 (StreamBuilder,PageView)

时间:2019-06-23 14:30:34

标签: flutter flutter-sliver stream-builder

我正在尝试创建一个包含在综合浏览量中的屏幕,该屏幕还包含部分屏幕的综合浏览量。

为实现这一点,我对整个页面本身具有无限的页面视图,然后每个页面都有一个页眉视图,下半部分具有一个带有3种可能选项的页面视图。我已经完成了很多工作,但是,我正在使用的页面我想要一个StreamBuilder ...这就是问题所在。

class DiaryPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _DiaryPage();
}

class _DiaryPage extends State<DiaryPage> with TickerProviderStateMixin {
  DiaryBloc _diaryBloc;
  TabController _tabController;
  PageController _pageController;

  @override
  void initState() {
    _diaryBloc = BlocProvider.of<DiaryBloc>(context);
    _diaryBloc.init();

    _tabController = TabController(length: 3, vsync: this);
    _pageController = PageController(initialPage: _diaryBloc.initialPage);

    super.initState();
  }

  @override
  void dispose() {
    _diaryBloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    return Flexible(
      child: PageView.builder(
        controller: _pageController,
        itemBuilder: (BuildContext context, int position) {
          return _buildPage(_diaryBloc.getDateFromPosition(position));
        },
        itemCount: _diaryBloc.amountOfPages,
      ),
    );
  }

  Widget _buildPage(DateTime date) {
    return Column(
      mainAxisSize: MainAxisSize.max,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[_getHeader(date), _getTabBody()],
    );
  }

  Widget _getHeader(DateTime date) {
    return Card(
      child: SizedBox(
        width: double.infinity,
        height: 125,
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.fromLTRB(8, 16, 8, 0),
              child: Text(
                '${DateFormat('EEEE').format(date)} ${date.day} ${DateFormat('MMMM').format(date)}',
                style: Theme.of(context).textTheme.subtitle,
                textScaleFactor: 1,
                textAlign: TextAlign.center,
              ),
            ),
            Row(
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                IconButton(
                  icon: const Icon(Icons.chevron_left),
                  onPressed: () => {
                        _pageController.previousPage(
                            duration: Duration(milliseconds: 250),
                            curve: Curves.ease)
                      },
                ),
                const Expanded(child: LinearProgressIndicator()),
                IconButton(
                  icon: const Icon(Icons.chevron_right),
                  onPressed: () => {
                        _pageController.nextPage(
                            duration: Duration(milliseconds: 250),
                            curve: Curves.ease)
                      },
                ),
              ],
            ),
            Container(
              height: 40.0,
              child: DefaultTabController(
                length: 3,
                child: Scaffold(
                  backgroundColor: Colors.white,
                  appBar: TabBar(
                    controller: _tabController,
                    unselectedLabelColor: Colors.grey[500],
                    labelColor: Theme.of(context).primaryColor,
                    tabs: const <Widget>[
                      Tab(icon: Icon(Icons.pie_chart)),
                      Tab(icon: Icon(Icons.fastfood)),
                      Tab(icon: Icon(Icons.directions_run)),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _getTabBody() {
    return Expanded(
      child: TabBarView(
        controller: _tabController,
        children: <Widget>[
          _getOverviewScreen(),
          _getFoodScreen(),
          _getExerciseScreen(),
        ],
      ),
    );
  }

  // TODO - this seems to be the issue, wtf and why
  Widget _getBody() {
    return Flexible(
      child: StreamBuilder<Widget>(
        stream: _diaryBloc.widgetStream,
        initialData: _diaryBloc.buildEmptyWidget(),
        builder: (BuildContext context, AsyncSnapshot<Widget> snapshot) {
          return snapshot.data;
        },
      ),
    );
  }

  Widget _getExerciseScreen() {
    return Text("Exercise Screen"); //_getBody();
  }

  Widget _getFoodScreen() {
    return Text("Food Screen"); //_getBody();
  }

  Widget _getOverviewScreen() {
    return _getBody();
  }
}

如您所见,在子页面视图中返回了三个小部件,其中两个是正确显示的文本小部件,但是正确填充了另一个文本小部件的StreamBuilder似乎给了我红色死亡之屏。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

解决了该问题,这与将StreamBuilder封装在Flexible(而不是一列)中有关。然后,我将column的mainAxisSize设置为max ...似乎可以正常工作。