Flutter:SingleChildScrollView 内的 TabBarView

Dan*_*ero 9 android scroll widget dart flutter

我的问题是我想要在 SingleChildScrollView 内有一个 TabBarView 但它给了我这个错误: RenderFlex子项具有非零弯曲但传入的高度约束是无界的。

如果我删除它,SingleChildScrollView它可以工作,但我需要这个小部件,因为然后我想推送一个随 一起滚动的 ListView TabBar,就像 Instagram 一样。

代码:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  TabController tabController;

  @override
  void initState() {
    super.initState();
    tabController = new TabController(length: 2, vsync: this);
  }

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: SingleChildScrollView(
      child: Column(
        children: [
          TabBar(
            controller: tabController,
            tabs: [
              Tab(
                icon: Icon(
                  Icons.photo_library,
                  size: 30,
                ),
              ),
              Tab(
                icon: Icon(
                  Icons.perm_media,
                  size: 30,
                ),
              ),
            ],
            labelColor: Colors.deepOrange,
            unselectedLabelColor: Colors.black,
            indicatorColor: Colors.deepOrange,
          ),
          Expanded(
            child: TabBarView(controller: tabController, children: [
              Expanded(child: Container()),
              Expanded(child: Container())
            ]),
          ),
        ],
      ),
    )));
  }
}

Run Code Online (Sandbox Code Playgroud)

变化:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  TabController tabController;

  @override
  void initState() {
    super.initState();
    tabController = new TabController(length: 2, vsync: this);
  }

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TabBar(
            controller: tabController,
            tabs: [
              Tab(
                icon: Icon(
                  Icons.photo_library,
                  size: 30,
                ),
              ),
              Tab(
                icon: Icon(
                  Icons.perm_media,
                  size: 30,
                ),
              ),
            ],
            labelColor: Colors.deepOrange,
            unselectedLabelColor: Colors.black,
            indicatorColor: Colors.deepOrange,
          ),
          Expanded(
            child: SingleChildScrollView(child:TabBarView(controller: tabController, children: [
              Container(),
              Container()
            ]),
          ),)
        ],
      ),
    ));
  }
}
Run Code Online (Sandbox Code Playgroud)

rev*_*_ss 17

您可以使用NestedScrollView它来解决此问题。

下面的代码帮助我解决了:

NestedScrollView(
      headerSliverBuilder: (context, value) {
        return [
          SliverToBoxAdapter(
              child: Header()
          ),
          SliverToBoxAdapter(
            child: TabBar(
              controller: _controller,
              tabs: [
                Tab(icon: Icon(Icons.x)),
                Tab(icon: Icon(Icons.y)),
                Tab(icon: Icon(Icons.z)),
              ],
            ),
          ),
        ];
      },
    body: Container(
      child: TabBarView(
        controller: _controller,
        children: <Widget>[
          page1(),
          page2(),
          page3(),
        ],
      ),
    ),
  )
Run Code Online (Sandbox Code Playgroud)

更详细的解释可以参考这个答案


Far*_*han 1

TabBarView 需要有限的高度,而 SingleChildScrollView 无法提供。问题是您正在 SingleChildScrollView 内的列中使用扩展。


类似问题的答案可能对您有帮助

答案就在错误本身。当该列位于可滚动视图内时,该列会尝试收缩包裹其内容,但由于您使用 Expanded 作为该列的子项,因此它的工作方式与尝试收缩包裹其子项的列相反。两者都试图实现完全相反的任务。奥格

这导致了此错误,因为这两个指令彼此完全相反。正如错误日志中提到的,请尝试以下操作:考虑设置mainAxisSizeMainAxisSize.min(对于列)并使用FlexFit.loose柔性拟合(使用柔性而不是扩展)。