系统“返回”按钮会关闭 Flutter 中的整个应用程序

问题描述 投票:0回答:1

大家好,我在 Flutter 应用程序中处理 Android 上的后退手势(后退按钮)时遇到问题。例如,我有一个使用 Navigator 的 pushNamed 功能推送的屏幕(登录屏幕是从欢迎屏幕推送的)。在该屏幕中,我希望应用程序返回到上一个屏幕,但应用程序却关闭了。这是代码。

路由器类

class AppRouter {
  Route<dynamic>? onGenerateRoute(RouteSettings routeSettings) {
    switch (routeSettings.name) {
      case '/login':
        return PageRouteBuilder(
            settings: routeSettings,
            pageBuilder: (_, __, ___) {
              return const LoginScreen();
            },
            // Pass this to make popUntil(), pushNamedAndRemoveUntil(), works
            transitionDuration: const Duration(milliseconds: 600),
            reverseTransitionDuration: const Duration(milliseconds: 450),
            transitionsBuilder: (_, a, __, c) => SlideTransition(
                position: Tween<Offset>(
                  begin: const Offset(1.0, 0.0), // From bottom
                  end: Offset.zero,
                ).animate(
                  CurvedAnimation(
                    parent: a,
                    curve: Curves.easeInOutCubicEmphasized,
                  ),
                ),
                child: c));
      default:
        return _materialRoute(const WelcomeScreen());
    }
  }

  static Route<dynamic> _materialRoute(Widget view) {
    return MaterialPageRoute(builder: (_) => view);
  }
}

main.dart

class MyApp extends StatefulWidget {
  const MyApp({super.key});

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

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.edgeToEdge,
    );

    return ScreenUtilInit(
        designSize: const Size(430, 932),
        minTextAdapt: true,
        splitScreenMode: true,
        builder: (_, child) {
          return MaterialApp(
            home: Navigator(
              key: navigatorKey,
              onGenerateRoute: AppRouter().onGenerateRoute,
            ),
          );
        });
  }
}

欢迎屏幕

class WelcomeScreen extends StatefulWidget {
  const WelcomeScreen({super.key});

  @override
  State<StatefulWidget> createState() {
    return _WelcomeScreenState();
  }
}

class _WelcomeScreenState extends State<WelcomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(20.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisSize: MainAxisSize.max,
            children: [
              SizedBox(
                width: double.infinity,
                child: ElevatedButton(
                  onPressed: () {
                    Navigator.of(context).pushNamed('/login');
                  },
                  child: const Text('Continue with E-Mail'),
                ),
              ),
              const SizedBox(
                height: 12,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

登录屏幕

class LoginScreen extends StatefulWidget {
  const LoginScreen({super.key});

  @override
  State<StatefulWidget> createState() {
    return _LoginScreenState();
  }
}

class _LoginScreenState extends State<LoginScreen> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: true,
      onPopInvoked: (didPop) => print('onPopInvoked didPop? $didPop'),
      child: Scaffold(
        appBar: AppBar(
            toolbarHeight: 0.09.sh,
            leadingWidth: 70,
            leading: Padding(
              padding: const EdgeInsets.only(left: 20),
              child: GestureDetector(
                onTap: () {
                  Navigator.of(context).pushReplacementNamed('/welcome');
                },
                child: SvgPicture.asset(
                  'assets/icons/back-in-circle.svg',
                  fit: BoxFit.contain,
                  color: Theme.of(context).brightness == Brightness.light
                      ? colorBlack
                      : null,
                ),
              ),
            )),
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.all(20.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              mainAxisSize: MainAxisSize.max,
              children: [
                Text("Login screen")
              ],
            ),
          ),
        ),
      ),
    );
  }
}

已将以下行添加到 AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    ...

    <application
        ...
        <activity
            ...
            android:enableOnBackInvokedCallback="true">
android flutter
1个回答
0
投票

您在

pushReplacementNamed
中使用
LoginScreen
而不是
pop

pushReplacementNamed
将当前路线替换为新路线。这就是应用程序关闭而不是返回欢迎屏幕的原因。

© www.soinside.com 2019 - 2024. All rights reserved.