getx icon indicating copy to clipboard operation
getx copied to clipboard

On Android, Back Button is closing the whole app in nested navigation

Open mehroze-zaidi opened this issue 2 years ago • 1 comments

Home-> ->Page A->Page A1 ->Page B

In nested navigation: I want to navigate back to Page A from Page A1 But When I press the back button (android) the app gets closed.

mehroze-zaidi avatar Sep 14 '22 10:09 mehroze-zaidi

@mehroze-zaidi this issue is not related to Getx.

You have to wrap your Scaffold() in Home with the widget WillPopScope()

loic-hamdi avatar Sep 14 '22 13:09 loic-hamdi

I have the same issue... I have tried application with MaterialApp and it is working fine But with GetMaterialApp , it is not working. It closes the whole App

a7mdragab avatar Sep 24 '22 09:09 a7mdragab

in addition to the very helpful answer from @loic-hamdi you should make sure you are browsing with Get.to() at this point.

kauemurakami avatar Sep 25 '22 18:09 kauemurakami

@a7mdragab @mehroze-zaidi It was a simple logic error, you must return false to "discard" willpop and use Get.back() to navigate backwards, it will not navigate to previous route if there is no previous route.

So your app can now go forward in the route stack and back as long as there is some route for it to come back.

/// DR.Ahmed_Ragab debugging project 
/// edit Kauê Murakami
import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  ///This is working
  // runApp(const MainApp());

  ///This is not working
  runApp(const GetMainApp());
}

class MainApp extends StatelessWidget {
  const MainApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Screen1(),
    );
  }
}

class Screen1 extends StatelessWidget {
  const Screen1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        print(Get.routeTree.routes.length);

        print("MoveToBackground 1");
        return true;
      },
      child: Scaffold(
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Screen1'),
            ElevatedButton(
              child: const Text('Screen2'),
              onPressed: () {
                Navigator.of(context)
                    .push(MaterialPageRoute(builder: (_) => const Screen2()));
              },
            ),
          ],
        )),
      ),
    );
  }
}

class Screen2 extends StatelessWidget {
  const Screen2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        print(Get.routeTree.routes.length);
        Get.back();
        print("MoveToBackground 2");
        return false;
      },
      child: Scaffold(
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Screen2'),
            ElevatedButton(
              child: const Text('Screen1'),
              onPressed: () {
                Navigator.of(context)
                    .push(MaterialPageRoute(builder: (_) => const Screen1()));
              },
            ),
          ],
        )),
      ),
    );
  }
}

class GetMainApp extends StatelessWidget {
  const GetMainApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      initialRoute: '/s1', popGesture: false,
      defaultTransition: Transition.fade,
      getPages: [
        GetPage(name: '/s1', page: () => const GetScreen1()),
        GetPage(name: '/s2', page: () => const GetScreen2()),
      ],
      // home: Screen1(),
    );
  }
}

class GetScreen1 extends StatelessWidget {
  const GetScreen1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        Get.back();
        print("MoveToBackground 1");
        return false;
      },
      child: Scaffold(
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Screen1'),
            ElevatedButton(
              child: const Text('Screen2'),
              onPressed: () {
                Get.toNamed('/s2');
              },
            ),
          ],
        )),
      ),
    );
  }
}

class GetScreen2 extends StatelessWidget {
  const GetScreen2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        print("MoveToBackground 2");
        return true;
      },
      child: Scaffold(
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Screen2'),
            ElevatedButton(
              child: const Text('Screen1'),
              onPressed: () {
                Get.toNamed('/s1');
              },
            ),
          ],
        )),
      ),
    );
  }
}

kauemurakami avatar Sep 25 '22 19:09 kauemurakami

Thanks for your reply But, for me, the onWillPop isn't called

a7mdragab avatar Sep 25 '22 19:09 a7mdragab

It doesn't make sense, try giving it a flutter clean. If you are browsing, routing is working the page is called and willpopscope is initialized on it accordingly.

kauemurakami avatar Sep 25 '22 21:09 kauemurakami