Search code examples
androidflutterdartnavigationflutter-go-router

Flutter: Android System Back Button Exits Application Instead of Popping Page


I'm developing a Flutter application and encountering an issue with the Android system back button. When I try to navigate back using the Android system back button, instead of popping the current page and returning to the previous one, the application exits. I am expecting that I when I use the system navigation on Android it would pop the payment settings screen back to the settings screen instead of just exit the whole application.

My flutter version for the project: 3.19.6 Dart version: Dart 3.3.4

settings.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:example/theme/theme.dart';
import 'package:example/widgets/app_drawer.dart';

class Settings extends StatelessWidget {
  const Settings({super.key});

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    return Scaffold(
      appBar: AppBar(
        backgroundColor: AppTheme.lightTheme.hintColor,
        title: Text(
          'Settings',
          style: AppTheme.lightTheme.textTheme.displayMedium!
              .copyWith(color: Colors.white),
          textAlign: TextAlign.center,
        ),
        centerTitle: true,
      ),
      drawer: const AppDrawer(),
      body: SafeArea(
        child: SingleChildScrollView(
          child: Container(
            height: size.height,
            width: size.width,
            decoration: BoxDecoration(
              color: AppTheme.lightTheme.hintColor,
            ),
            child: Container(
              height: size.height,
              width: size.width,
              decoration: BoxDecoration(
                borderRadius: const BorderRadius.only(
                  topLeft: Radius.circular(15),
                  topRight: Radius.circular(15),
                ),
                color: AppTheme.lightTheme.dialogBackgroundColor,
              ),
              child: Align(
                alignment: Alignment.topLeft,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Padding(
                      padding: EdgeInsets.only(left: 30, top: 30),
                      child: Text(
                        'Preference',
                        style: AppTheme.lightTheme.textTheme.headlineLarge!
                            .copyWith(fontSize: 18),
                        textAlign: TextAlign.left,
                      ),
                    ),
                    const SizedBox(
                      height: 10,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(left: 30),
                      child: OptionListItem(context, 'Appearance', '/home'),
                    ),
                    Divider(
                      thickness: 0.5,
                      color: AppTheme.lightTheme.dividerColor,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(left: 30),
                      child: OptionListItem(context, 'Notifications', '/home'),
                    ),
                    Divider(
                      thickness: 0.5,
                      color: AppTheme.lightTheme.dividerColor,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(left: 30),
                      child: OptionListItem(context, 'Accessibility', '/home'),
                    ),
                    Divider(
                      thickness: 0.5,
                      color: AppTheme.lightTheme.dividerColor,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(left: 30),
                      child: OptionListItem(context, 'Language', '/home'),
                    ),
                    Divider(
                      thickness: 0.5,
                      color: AppTheme.lightTheme.dividerColor,
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(left: 30),
                      child: Text(
                        'Payments',
                        style: AppTheme.lightTheme.textTheme.headlineLarge!
                            .copyWith(fontSize: 18),
                        textAlign: TextAlign.left,
                      ),
                    ),
                    const SizedBox(
                      height: 10,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(left: 30),
                      child: OptionListItem(
                          context, 'Payment Settings', '/payment_settings'),
                    ),
                    Divider(
                      thickness: 0.5,
                      color: AppTheme.lightTheme.dividerColor,
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget OptionListItem(BuildContext context, String label, String path) {
    return GestureDetector(
        onTap: () => GoRouter.of(context).push(path),
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 10),
          child: Container(
            width: double.infinity,
            height: 20,
            child: Text(
              label,
              style: AppTheme.lightTheme.textTheme.displaySmall!
                  .copyWith(color: Colors.black, fontSize: 16),
            ),
          ),
        ));
  }
}

payment_settings.dart

import 'package:flutter/material.dart';
import 'package:example/widgets/app_appbar.dart';

class PaymentSettings extends StatelessWidget {
  const PaymentSettings({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      appBar: AppAppbar(
        title: 'Payment Settings',
      ),
      body: Center(
        child: Text('This is the payment settings page.'),
      ),
    );
  }
}

routes.dart

import 'package:go_router/go_router.dart';
import 'package:example/page/home_screen.dart';
import 'package:example/page/payment_settings_page.dart';
import 'package:example/page/settings_screen.dart';


class AppRoute {
  GoRouter route = GoRouter(
    initialLocation: '/home',
    routes: <RouteBase>[
      GoRoute(
        path: '/',
        builder: (context, state) => const Home(),
      ),
      GoRoute(
        path: '/home',
        builder: (context, state) => const Home(),
      ),

      GoRoute(
        path: '/settings',
        builder: (context, state) => const Settings(),
      ),

      GoRoute(
        path: '/payment_settings',
        builder: (context, state) => const PaymentSettings(),
      ),


    ],
  );
}

I have tried searching solutions online and I've noticed that there are some people saying that this is the GoRouter's problem. But I really need GoRouter for my project is there any solution that can help me solve this issue?

This is the post I have came across (https://github.com/flutter/flutter/issues/140869)


Solution

  • import 'package:flutter/material.dart'; import 'package:example/widgets/app_appbar.dart';

    class PaymentSettings extends StatelessWidget { const PaymentSettings({super.key});

    @overridee Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { Navigator.push( context, MaterialPageRoute( builder: (context) => Settings(), ), ); return true; },

      child: const Scaffold(
        appBar: AppAppbar(
          title: 'Payment Settings',
        ),
        body: Center(
          child: Text('This is the payment settings page.'),
        ),
      ),
    );
    

    } }