skip to Main Content

From this container/widget

enter image description here

To this container/widget

enter image description here

How can i navigator a container/widget from the first container/widget to the container/widget. Just click the icon forward/back in flutter ??

  • As you’ve seen. Above I have 2 images. I want when I click on the continue arrow icon, it will switch to the Widget in the next image.
    I want to keep the appBar part,… I just want the Box part to move. Thank you very much

2

Answers


  1. This can be achieved using PageView and PageController:

    class StackHelp extends StatefulWidget {
      const StackHelp({super.key});
    
      @override
      State<StackHelp> createState() => _StackHelpState();
    }
    
    class _StackHelpState extends State<StackHelp> {
      Container container1 = Container(color: Colors.green);
      Container container2 = Container(color: Colors.blue);
      Container container3 = Container(color: Colors.yellow);
      Container container4 = Container(color: Colors.cyan);
    
      //Page Controller to navigate between pages
      final PageController controller = PageController();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: Center(
            child: Stack(
              alignment: Alignment.bottomCenter,
              children: [
                Container(
                  margin: const EdgeInsets.all(8.0),
                  color: Colors.grey,
                  height: MediaQuery.of(context).size.height * .50,
                  child: PageView(
                    controller: controller,
                    children: [
                      container1,
                      container2,
                      container3,
                      container4,
                    ],
                  ),
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    IconButton(
                      onPressed: () {
                        controller.previousPage(
                          duration: const Duration(milliseconds: 100),
                          curve: Curves.linear,
                        );
                      },
                      icon: const Icon(Icons.arrow_back),
                    ),
                    IconButton(
                      onPressed: () {
                        controller.nextPage(
                          duration: const Duration(milliseconds: 100),
                          curve: Curves.linear,
                        );
                      },
                      icon: const Icon(Icons.arrow_forward),
                    ),
                  ],
                ),
              ],
            ),
          ),
        );
      }
    }
    

    demo

    Login or Signup to reply.
  2. Unless you need something more sophisticated for navigation between nested widgets (each container having its own state, its own controller, etc), you could easily achieve it using the one stateful widget and a bunch of nested widgets. (they can be stateful or inherited widgets too if needed)

    E.g.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const MyHomePage(title: 'Card navigator'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key, required this.title});
    
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int currentWidget = 0;
      final List<MyWidget> widgets = [
        const MyWidget(
          cardId: "1",
          cardColor: Colors.blue,
        ),
        const MyWidget(
          cardId: "2",
          cardColor: Colors.red,
        ),
      ];
      void _moveToNext() {
        setState(() {
          currentWidget++;
        });
      }
    
      void _moveToPrevious() {
        setState(() {
          currentWidget--;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        final MyWidget selectedWidget = widgets[currentWidget];
    
        final bool previousExists = currentWidget != 0;
        final bool nextExists = currentWidget != widgets.length - 1;
    
        return Scaffold(
          appBar: AppBar(
              backgroundColor: Theme.of(context).colorScheme.inversePrimary,
              title: Text(widget.title),
              leading: IconButton(
                icon: Icon(Icons.arrow_back),
                onPressed: previousExists ? () => _moveToPrevious() : null,
              ),
              actions: [
                IconButton(
                  icon: Icon(Icons.arrow_forward),
                  onPressed: nextExists ? () => _moveToNext() : null,
                )
              ]),
          body: Center(
            child: MyWidget(
              cardId: selectedWidget.cardId,
              cardColor: selectedWidget.cardColor,
            ),
          ),
        );
      }
    }
    
    class MyWidget extends StatelessWidget {
      final String cardId;
      final Color cardColor;
      const MyWidget(
          {super.key, this.cardId = "None", this.cardColor = Colors.black});
    
      @override
      Widget build(BuildContext context) {
        return Container(
          constraints: const BoxConstraints(maxHeight: 200.0, maxWidth: 200.0),
          alignment: Alignment.center,
          decoration: BoxDecoration(
            color: cardColor,
            border: Border.all(),
            borderRadius: const BorderRadius.all(Radius.circular(2.0)),
          ),
          child: Text("Card $cardId!"),
        );
      }
    }
    

    If you need something more production-ready to keep a good de-coupling, then there are several other ways:

    • If the set of pages is not pre-defined or you are sure that the logic inside every widget is not gonna be expanding, I would suggest using the solution recommended above with PageView.
    • If every page is independent && you potentially foresee them growing in the future with more layout components inside(more fields, buttons) && you would want users to continue where they stopped after they close/open the app – I would suggest looking at routing for navigation https://docs.flutter.dev/cookbook/navigation/navigation-basics.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search