如何结合pushNamed与Dismissible Widget实现下拉返回显示首页面
问题
我想用Flutter的pushNamed从FirstScreen跳转到SecondScreen,同时用Dismissible实现下拉关闭SecondScreen。但下拉关闭时会出现黑屏,我希望下拉过程中能看到FirstScreen。我用了官方命名路由示例代码,具体实现如下:
class FirstScreen extends StatelessWidget { const FirstScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('First Screen'), ), body: Center( child: ElevatedButton( onPressed: () { Navigator.pushNamed(context, '/second'); }, child: const Text('Launch screen'), ), ), ); } } class SecondScreen extends StatelessWidget { const SecondScreen({super.key}); @override Widget build(BuildContext context) { return Dismissible( key: UniqueKey(), movementDuration: const Duration(milliseconds: 0), resizeDuration: const Duration(milliseconds: 1), onDismissed: (d) => Navigator.of(context).pop(), direction: DismissDirection.down, child: Scaffold( appBar: AppBar( title: const Text('Second Screen'), ), body: Center( child: ElevatedButton( onPressed: () { Navigator.pop(context); }, child: const Text('Go back!'), ), ), ), ); } }
我发现用PageRouteBuilder设置opaque: false能实现效果,但不想用这种写法:
Navigator.of(context).push( PageRouteBuilder( opaque: false, pageBuilder: (context, animation, secondaryAnimation) => const SecondScreen(), )); void main() { runApp( MaterialApp( title: 'Named Routes Demo', initialRoute: '/', routes: { '/': (context) => const FirstScreen(), '/second': (context) => const SecondScreen(), }, ), ); }
解决办法
黑屏的原因是默认的MaterialPageRoute是**不透明(opaque=true)**的,下拉时页面下方没有内容就会显示黑屏。要让命名路由也支持透明效果,你可以自定义路由规则,在MaterialApp的onGenerateRoute里配置:
void main() { runApp( MaterialApp( title: 'Named Routes Demo', initialRoute: '/', // 用onGenerateRoute替代原有的routes配置 onGenerateRoute: (settings) { switch (settings.name) { case '/': return MaterialPageRoute( builder: (context) => const FirstScreen(), opaque: true, // 首页保持不透明 ); case '/second': return MaterialPageRoute( builder: (context) => const SecondScreen(), opaque: false, // 设为透明,让下方页面可见 ); default: return null; } }, ), ); }
另外可以调整SecondScreen的Scaffold背景,避免完全透明导致内容显示异常:
child: Scaffold( backgroundColor: Colors.white.withOpacity(0.95), // 给页面加半透明背景 appBar: AppBar( title: const Text('Second Screen'), ), // ... 原有代码 )
同时建议去掉movementDuration: const Duration(milliseconds: 0)这类强制关闭动画的设置,让下拉关闭的过渡更自然。
这样配置后,用Navigator.pushNamed(context, '/second')跳转时,SecondScreen的路由会变成透明的,下拉Dismissible就能看到下方的FirstScreen了,同时保留了命名路由的使用方式。
内容的提问来源于stack exchange,提问作者SHINNAKRONKIT NARKASEN
相关产品推荐
相关产品推荐

