Search code examples
tabsdartflutterappbarflutter-appbar

Flutter Appbar (actions) with child tabs


I'm new in Flutter and I wonder if you can help me to find a solution to my problem.

I have a scaffold with a tabview and I want to make a filter (actions button) in the main appbar to manage tabs.

Both main and child are StatefulWidgets

here's my code of the main page :

Widget body = TabBarView(
      controller: tabController,
      children: <Widget>[
        new First(filter: filter),
        new Second(filter: filter);
        new Third(filter: filter);
      ],
    );
return Scaffold(
    appBar: AppBar(
           actions:[IconButton(icon: Icon(MdiIcons.filter),onPressed: 
           () {
              // Send info to child 
           })],
           bottom: new TabBar(
           controller: tabController,
           tabs: <Tab>[
             new Tab(text:"Tab1"),
             new Tab(text:"Tab2"),
             new Tab(text:"Tab3")
           ],
    body: new Builder(builder: (BuildContext context) {
      _scaffoldContext = context;
      return body;
    }));
));

Children page :

Widget body = Text("Filter name here");
return Scaffold(
  body: 
  new Builder(
    builder: (context) {
      snack = new DisplaySnackBar(context: context);
      return body;
    }),
);
}

I don't know where to put the actions of appbar to make Text on child's body changes from the main page.


Solution

  • I found the solution by making my parent widget as an InheritedWidget so I can access to it's data from child.

    Here's an example :

    class MyStatefulWidget extends StatefulWidget{
    @override
      MyStatefulWidgetState createState() => MyStatefulWidgetState();
    
      static MyStatefulWidgetState of(BuildContext context){
        return (context.inheritFromWidgetOfExactType(_MyInheritedStateContainer) as _MyInheritedStateContainer).data;
      }
    }
    class MyStatefulWidgetState extends State<MyStatefulWidget>{
    
    String variableCalledHello = "Hello World";
    @override
      void initState() {
        super.initState();
      }
     @override
      Widget build(BuildContext context) {
       return new _MyInheritedStateContainer(data:this,child:/* Body here */);
      }
    }
    class _MyInheritedStateContainer extends InheritedWidget{
        _MyInheritedStateContainer({
    Key key,
        @required Widget child,
        @required this.data,
      }) : super(key: key, child: child);
    
    final MyStatefulWidgetState data;
    
     @override
      bool updateShouldNotify(_MyInheritedStateContainer oldWidget) {
        return true;
      }
    }
    

    and for every child :

    you just have to call MyStatefulWidgetState state = MyStatefulWidgetState.of(context);

    example :

    @override
      Widget build(BuildContext context) {
       MyStatefulWidgetState state = MyStatefulWidgetState.of(context);
    
       print(state.variableCalledHello);
    
       return /* Container ... */;
    
    }
    

    Hope that will help someone to solve his problem.

    Thanks.