Home > database >  How to use Navigator 2.0 to navigate to any page?
How to use Navigator 2.0 to navigate to any page?

Time:11-01

I'm trying to navigate to multiple pages from a single page, when user taps on the elevated button it should take the user to the desired page. I can't figure out how to navigate. Here is my main.dart file. And what is the use of ValueKey?


void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  void _handleEmail(String email) {
    setState(() {
      _emailController.text = email;
    });
    print(email);
  }

  void _handlePassword(String password) {
    setState(() {
      _passwordController.text = password;
    });
    print(password);
  }

  bool _logIn = true;
  int selectedPage = 0;
  @override
  Widget build(BuildContext context) {
    final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
    return MaterialApp(
      home: Navigator(
        key: navigatorKey,
        pages: [
          if (selectedPage == 0)
            MaterialPage(
              key: const ValueKey("login"),
              child: Login(
                isLogin: (value) {
                  setState(() {
                  //  _logIn = !_logIn;
                    _logIn = value;
                //    print(_logIn);
                  });
                },
                onTapOne: _handleEmail,
                onTapTwo: _handlePassword,
              ),
            ),
          if (_logIn)
            MaterialPage(
                key: Home.valueKey,
                child: Home(
                  selectedPage: (value) {
                    setState(() {
                      selectedPage = value;
                    });
                  },
                  email: _emailController.text,
                  password: _passwordController.text,
                  onTap: _handleEmail,
                )),
          if (selectedPage == 1) MaterialPage(child: Cart()),
          if (selectedPage == 2) const MaterialPage(child: Profile()),
          if (selectedPage == 3) const MaterialPage(child: CheckOut()),
        ],
        onPopPage: (route, result) {
          _logIn = false;
          selectedPage = 0;
          return route.didPop(result);
        },
      ),
    );
  }
}

below is the code for the screen from where I can navigate to any screen.


class Home extends StatefulWidget {
  Home({
    Key? key,
    required this.password,
    required this.onTap,
    required this.email,
    required this.selectedPage,
  }) : super(key: key);
  String email;
  String password;
  final ValueChanged<String> onTap;
  final ValueChanged<int> selectedPage;
  static const valueKey = const ValueKey("home");

  @override
  State<Home> createState() => _HomeState();
}

int selectedPage = 0;

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amber,
      appBar: AppBar(
        title: Text('${widget.email}: Home'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("${widget.password}"),
            ElevatedButton(
                onPressed: () {
                  setState(() {
                    selectedPage = 1;
                  });
                },
                child: Text("go to CART")),
            ElevatedButton(onPressed: () {}, child: Text("go to LOGIN")),
            ElevatedButton(
                onPressed: () {
                  setState(() {
                    selectedPage = 2;
                  });
                },
                child: Text("go to PROFILE")),
            ElevatedButton(
                onPressed: () {
                  setState(() {
                    selectedPage = 3;
                  });
                },
                child: Text("go to CHECKOUT")),
          ],
        ),
      ),
    );
  }
}

CodePudding user response:

As for your Home can be simpler:

class MyButton {
  int? id;
  String? label;


  MyButton({
    this.id,
    this.label,
  })
/// Add More logic here if you want to
}

class Home extends StatefulWidget {
  Home({
    Key? key,
    required this.password,
    required this.onTap,
    required this.email,
    required this.selectedPage,
  }) : super(key: key);
  String email;
  String password;
  final ValueChanged<String> onTap;
  final ValueChanged<int> selectedPage;
  static const valueKey = const ValueKey("home");

  @override
  State<Home> createState() => _HomeState();
}

int? selectedPage;

class _HomeState extends State<Home> {
  List<MyButton>? _myButton = [
    MyButton(id: 0, label: 'Go to Cart'),
    MyButton(id: 1, label: 'Go to profile'),
    MyButton(id: 2, label: 'Go to something'),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amber,
      appBar: AppBar(
        title: Text('${widget.email}: Home'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: _myButton!.map((button) {
            return ElevatedButton(
                onPressed: () {
                  super.setState(() =>selectedPage = button.id!);
                },
                child: Text(button.label!);
          } ).toList(),
        ),
      ),
    );
  }
}

as for navigation, I would recommend using the navigator method just to minimise complexity over time. I would propose:

Navigator(

  pages: [
    MaterialPage(
        key: const ValueKey("login"), // Separate it
        child: _onSelectedPage(),
    ),
  ],
),


dynamic _onSelectedPage() {
  switch(selectedPage) {
    case 0:
      if(_logIn) {
        return Home(
          selectedPage: (value) {},
          email: _emailController.text,
          password: _passwordController.text,
          onTap: _handleEmail,
        );
      }

      return Login(
        isLogin: (value) {},
        onTapOne: _handleEmail,
        onTapTwo: _handlePassword,
      );

    case 1:
      return Cart();
    
    case 2:
      return Profile();

    case 3:
      return CheckOut();

    default:
      break;
  }
}
  • Related