One tab using TabBarView contains multiple methods [Flutter]

534

Solution 1

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

Solution 2

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.

Share:
534
Don
Author by

Don

Junior Software Engineer

Updated on December 30, 2022

Comments

  • Don
    Don over 1 year

    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:

    For Movie

    For TV Show

    Any help would be great. Thanks in advance :)

  • Don
    Don almost 3 years
    Well thats just a partial fix, still it doesn't display both widgets which I want at the same time: NowPlayedMovies() and BestMovies() - when movies are pressed and NowPlayedTV() and BestTV() - when tv shows are pressed
  • Don
    Don almost 3 years
    Ok so I fixed the issue completely, thx for giving me a guide in the right direction