You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:58:03