Search code examples
flutterflutter-layoutflutter-webflutter-animation

Change TabbarView in Flutter When pressed button from another class and also need to make swipe-able


Hey I m new in flutter now m stuck with the tab bar I have four files (Class), the first one is the parent file and the other three files(Class) are the child.

Now I want to change tabbarview when I clicked the button from the child class.

I also shared my sample code please help me.

This is My Parent Class

class AddItemTab extends StatefulWidget {
  const AddItemTab({Key? key}) : super(key: key);

  @override
  _AddItemTabState createState() => _AddItemTabState();
}

class _AddItemTabState extends State<AddItemTab> {

  final List<Widget> _fragments = [
    const ProductPurchase(),
    const ProtectionProduct(),
    const RoomProduct()
  ];
  int _page = 0;

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
          backgroundColor: MyColor.backgroundColor,
          body: Padding(
            padding: const EdgeInsets.only(
                top: 50.0, right: 20.0, left: 20.0, bottom: 20.0),
            child: Container(
              child: Column(
                children: [
                  Row(
                    children: [
                      Align(
                        alignment: Alignment.centerLeft,
                        child: IconButton(
                          padding: EdgeInsets.zero,
                          constraints: BoxConstraints(),
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                          icon: const Icon(Icons.arrow_back_ios),
                        ),
                      ),
                      Text("Back"),
                    ],
                  ),
                  SizedBox(
                    height: 15,
                  ),
                  const Align(
                      alignment: Alignment.centerLeft,
                      child: Text(
                        'Add an item',
                        style: TextStyle(
                          color: Colors.black,
                          fontSize: 34,
                          fontFamily: 'Inter',
                          fontWeight: FontWeight.w700,
                        ),
                      )),
                  const SizedBox(
                    height: 15,
                  ),
                  Container(
                    height: 55,
                    width: double.infinity,
                    child: const TabBar(
                      indicator: BoxDecoration(
                        color: MyColor.buttonColor,
                        borderRadius: BorderRadius.all(
                          Radius.circular(5),
                        ),
                      ),

                      indicatorWeight: 5,
                      indicatorPadding: EdgeInsets.only(top:50),
                      // controller: _tabController,
                      labelColor: Colors.black,
                      tabs: [
                        Tab(
                          child: Text(
                            "Purchase",
                            textAlign: TextAlign.center,
                          ),
                        ),
                        Tab(
                          text: 'Protection',
                        ),
                        Tab(
                          text: 'Room',
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 20),
                  Expanded(
                      child: TabBarView(
                    children: [
                      _fragments[0],
                      _fragments[1],
                      _fragments[2],
                    ],
                  ))
                ],
              ),
            ),
          )),
    );
  }
} 

This is My Child Class

class ProductPurchase extends StatefulWidget {
  const ProductPurchase({Key? key}) : super(key: key);

  @override
  _ProductPurchaseState createState() => _ProductPurchaseState();
}

class _ProductPurchaseState extends State<ProductPurchase> {
  final List<Widget> _fragments = [
    const ProtectionProduct(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: MyColor.backgroundColor,
      body: Stack(
        children: [
          Padding(
            padding: EdgeInsets.only(bottom: 50),
            child: Align(
              alignment: Alignment.bottomCenter,
              child: ElevatedButton(
                style: ElevatedButton.styleFrom(
                  padding: EdgeInsets.zero,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                  elevation: 5,
                ),
                onPressed: () {
                  // Navigator.of(context).push(MaterialPageRoute(
                  //     builder: (context) => ProductView()));
                  // _fragments[0];
                },
                child: Ink(
                  decoration: BoxDecoration(
                      color: MyColor.buttonColor,
                      borderRadius: BorderRadius.circular(10)),
                  child: Container(
                    width: 250,
                    padding: const EdgeInsets.all(15),
                    constraints: const BoxConstraints(minWidth: 88.0),
                    child: const Text('Go To Next Tabbar View',
                        textAlign: TextAlign.center,`enter code here`
                        style: TextStyle(
                            fontSize: 18,
                            fontWeight: FontWeight.bold,
                            color: Colors.white)),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
} 

Solution

  • You need to use TabController for this , while you already have tab Bar and tab Bar view, you can do it like

    class _AddItemTabState extends State<AddItemTab>
        with SingleTickerProviderStateMixin {
      final List<Widget> _fragments = [
      .....
      ];
    
      late final TabController controller = TabController(length: 3, vsync: this);
      @override
      Widget build(BuildContext context) {
     
    
    ........
    
    child: TabBar(
      controller: controller,
    
    ......
    Expanded(
          child: TabBarView(
        controller: controller,
    

    And to move n index, here 2

    onPressed: () {
      controller.animateTo(2);
    },
    

    To call from different widget using callback method

    class ProductPurchase extends StatefulWidget {
      final VoidCallback callback;
      const ProductPurchase({Key? key, required this.callback}) : super(key: key);
    
    .....
    onPressed:  (){
      widget.callback();
    },
    
    

    Once you used this widget, provide

    ProductPurchase(callback: (){
      controller.animateTo(2);
    },);
    
    class ProductPurchase extends StatefulWidget {
      final VoidCallback callback;
      const ProductPurchase({Key? key, required this.callback}) : super(key: key);
    
      @override
      _ProductPurchaseState createState() => _ProductPurchaseState();
    }
    
    class _ProductPurchaseState extends State<ProductPurchase> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          // backgroundColor: MyColor.backgroundColor,
          body: Stack(
            children: [
              Padding(
                padding: EdgeInsets.only(bottom: 50),
                child: Align(
                  alignment: Alignment.bottomCenter,
                  child: ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      padding: EdgeInsets.zero,
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10)),
                      elevation: 5,
                    ),
                    onPressed: () {
                      widget.callback(); //this
                    },
                    child: Ink(
                      decoration: BoxDecoration(
                          color: MyColor.buttonColor,
                          borderRadius: BorderRadius.circular(10)),
                      child: Container(
                        width: 250,
                        padding: const EdgeInsets.all(15),
                        constraints: const BoxConstraints(minWidth: 88.0),
                        child: const Text('Go To Next Tabbar View',
                            textAlign: TextAlign.center,
                            style: TextStyle(
                                fontSize: 18,
                                fontWeight: FontWeight.bold,
                                color: Colors.white)),
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }
    

    And fragments

      late final List<Widget> _fragments = [
        ProductPurchase(
          callback: () {
            controller.animateTo(3);
          },
        ),
        Container(color: Colors.cyanAccent, child: Stack(children: [Text("fsA")])),
        Text("2A")
      ];
    

    More about TabBar