You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter:禁用页面返回且保留Hero组件动画?Navigator方法致动画失效

Great question! The issue with pushAndRemoveUntil and pushReplacement is that they modify the navigation stack during the transition, which breaks Hero animations—Hero relies on both the source and destination routes being present in the stack while the animation runs.

Here's a clean solution that preserves the Hero transition while preventing users from navigating back to the Splash screen:

Step 1: Use a regular Navigator.push for the initial transition

Instead of replacing or removing routes upfront, keep the Splash route in the stack temporarily so the Hero animation can complete normally:

// In your SplashScreen widget
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => LoginPage()),
);

Step 2: Block back navigation in the LoginPage

Use Flutter's PopScope (recommended for Flutter 3.12+) or WillPopScope (for older versions) to intercept back button presses, preventing users from returning to the Splash screen.

Using PopScope (Flutter 3.12+)

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return PopScope(
      // Disable default back navigation
      canPop: false,
      onPopInvoked: (didPop) {
        // Optional: Add custom logic here (e.g., show a confirmation dialog)
        // If you don't need any feedback, leave this empty
      },
      child: Scaffold(
        body: Center(
          // Your Hero widget matching the one in SplashScreen
          child: Hero(
            tag: 'splash-logo',
            child: Image.asset('assets/logo.png'),
          ),
        ),
      ),
    );
  }
}

Using WillPopScope (pre-Flutter 3.12)

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        // Return false to block the back navigation
        return false;
      },
      child: Scaffold(
        // Your LoginPage UI including the Hero widget
      ),
    );
  }
}

Once the user successfully logs in, you can safely clear the Splash and Login routes from the stack using pushAndRemoveUntil—this won't affect the original Hero animation since it's already completed:

// In LoginPage, after successful authentication
Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute(builder: (context) => HomePage()),
  (route) => false, // Removes all previous routes
);

This approach keeps the Hero animation intact because the Splash route stays in the stack during the transition, and we only block navigation back rather than removing the route immediately. It's the best of both worlds!

内容的提问来源于stack exchange,提问作者Alejandro Gabriel

火山引擎 最新活动