一个tab使用TabBarView包含多种方法【Flutter】

One tab using TabBarView contains multiple methods [Flutter]

我想要做的是当按下电影选项卡时它显示 NowPlayedMovies() 和 BestMovies(),当按下电视时显示选项卡以显示 NowPlayedTV() 和 BestTV()。起初我使用的是 ListView,但因为我使用的是选项卡,所以我需要使用 TabBarView。因此,在我的子方法中,我创建了 2 个方法 buildPage1 和 buildPage2,其中我已经放置了上面提到的 2 个方法。

当我尝试 运行 代码时,它显示了这个错误:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building _TabControllerScope:
The getter 'key' was called on null.
Receiver: null
Tried calling: key

The relevant error-causing widget was:
  DefaultTabController

这是我的代码:

class HomePageMovie extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePageMovie> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Color(0xFF151C26),
        appBar: AppBar(
          backgroundColor: Color(0xFF151C26),
          title: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              SvgPicture.asset(
                logo,
                height: 195,
              ),
            ],
          ),
          actions: <Widget>[
            IconButton(
                onPressed: () {},
                icon: Icon(
                  EvaIcons.searchOutline,
                  color: Colors.white,
                ))
          ],
          titleSpacing: 0.0,
          bottom: PreferredSize(
            preferredSize: Size.fromHeight(75.0),
            child: DefaultTabController(
              length: 2,
              child: TabBar(
                  indicatorColor: Color(0xFFf4C10F),
                  indicatorWeight: 4.0,
                  unselectedLabelColor: Colors.white,
                  labelColor: Colors.white,
                  tabs: [
                    Tab(
                      icon: Icon(Icons.movie),
                      child: Text(
                        "Movies",
                        style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontSize: 14.0),
                      ),
                    ),
                    Tab(
                      icon: Icon(Icons.live_tv),
                      child: Text(
                        "TV Shows",
                        style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontSize: 14.0),
                      ),
                    )
                  ]),
            ),
          ),
        ),
        body: DefaultTabController(
          length: 2,
          child: TabBarView(
            children: [buildPage1(), buildPage2()],
          ),
        ));
  }

  buildPage1() {
    NowPlayingMovies();
    BestMovie();
  }

  buildPage2() {
    NowPlayingTV();
    BestTV();
  }
}

这是我要实现的目标的直观表示:

任何帮助都会很棒。提前致谢:)

只使用一个 DefaultTabBarController 在你的小部件树的顶部(在这种情况下,作为你的 Scaffold 的父级并删除另外两个)。

您应该只使用在 TabBarTabBarView 之间共享的单个 DefaultTabBarController

因此,在 Miguel 的帮助下,我做错的是我没有放置特定的控制器来连接这两个控制器,在我的例子中,作为一种解决方案,我将它们都包装在通用的默认控制器中。至于问题的第二部分,我所做的只是简单地让 ListView 显示这些 2

解法代码:

class _HomePageState extends State<HomePageMovie> {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        backgroundColor: Color(0xFF151C26),
        appBar: AppBar(
          backgroundColor: Color(0xFF151C26),
          title: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              SvgPicture.asset(
                logo,
                height: 195,
              ),
            ],
          ),
          actions: <Widget>[
            IconButton(
                onPressed: () {},
                icon: Icon(
                  EvaIcons.searchOutline,
                  color: Colors.white,
                ))
          ],
          titleSpacing: 0.0,
          bottom: PreferredSize(
            preferredSize: Size.fromHeight(75.0),
            child: TabBar(
                indicatorColor: Color(0xFFf4C10F),
                indicatorWeight: 4.0,
                unselectedLabelColor: Colors.white,
                labelColor: Colors.white,
                tabs: [
                  Tab(
                    icon: Icon(Icons.movie),
                    child: Text(
                      "Movies",
                      style: TextStyle(
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                          fontSize: 14.0),
                    ),
                  ),
                  Tab(
                    icon: Icon(Icons.live_tv),
                    child: Text(
                      "TV Shows",
                      style: TextStyle(
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                          fontSize: 14.0),
                    ),
                  )
                ]),
          ),
        ),
        body: TabBarView(
          children: [
            ListView(
              children: <Widget>[NowPlayingMovies(), BestMovie()],
            ),
            ListView(
              children: <Widget>[
                NowPlayingTV(),
                BestTV(),
              ],
            ),
          ],
        ),
      ),
    );
  }
}