简体   繁体   中英

One tab using TabBarView contains multiple methods [Flutter]

What I want to do is to when pressed a movie tab it shows NowPlayedMovies() and BestMovies(), and when pressed tv shows tab to show NowPlayedTV() and BestTV(). At first I was using ListView but because I'm using tabs i need to use TabBarView. So in my child method I created 2 methods buildPage1 and buildPage2 in which I have put my 2 methods as mentioned above.

When I tried to run the code it displayed this error:

══╡ 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

Here is my code:

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();
  }
}

Here is visual representation of what I'm trying to achieve:

电影

电视节目

Any help would be great. Thanks in advance :)

Use only one DefaultTabBarController at the top of your widget tree (in this case, as a parent of your Scaffold and remove the other two).

You should only use a single DefaultTabBarController that is shared between the TabBar and the TabBarView .

So with help of Miguel what I did wrong was I didn't put a specific controller to connect these 2, in my case as a solution I wrapped them both in common default controller. As of the 2nd part of the problem what I did is simply put ListView to display these 2

The code of solution:

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(),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM