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

页面切换时Scaffold主体出现黑色边框的问题求助

页面导航时出现黑色边框的问题

在我的Web应用中进行页面导航时,会出现奇怪的黑色边框。我希望保留现有的缩放动画,但消除这个黑色边框。需要说明的是,内容区域下方没有黑色图层,这看起来像是动画故障。

相关代码片段

MyScaffold 组件

class MyScaffold extends StatelessWidget {
  const MyScaffold({
    super.key,
    required this.state,
    required this.child,
  });

  final GoRouterState state;
  final Widget child;
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: //...,
      body: AdaptiveLayout( // 使用 flutter_adaptive_scaffold 包
        internalAnimations: false,
        primaryNavigation: // 大屏使用 NavigationRail
        bottomNavigation: // 小屏使用 NavigationBar
        body: SlotLayout(
          config: {
            Breakpoints.smallAndUp: SlotLayout.from(
              key: PortalScaffold.bodyKey,
              builder: (_) => Container(
                clipBehavior: Clip.hardEdge,
                decoration: const BoxDecoration(),
                constraints: const BoxConstraints.expand(),
                child: child,
              ),
            ),
          },
        ),
      ),
    );
  }
}

MyPage 组件

class MyPage extends StatelessWidget {
  const MyPage({super.key});
  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final t = AppLocalizations.of(context)!;
    return Scaffold(
      body: Container(
        color: theme.colorScheme.background,
        constraints: const BoxConstraints.expand(),
        child: Text(t.myPageLabel),
      ),
    );
  }
}

路由配置

final _routerConfig = GoRouter(
  // ...
  routes: [
    // ...
    ShellRoute( // ShellRoute 使导航组件在页面切换时保留
      builder: (context, state, child) {
        return MyScaffold(state: state, child: child);
      },
      routes: [
        // ...
        GoRoute(
          path: // ...
          builder: (context, state) => const MyPage(),
        );
      ]
    )
  ]
);

MaterialApp.router(
  // ...
  routerConfig: _routerConfig
);

生成的布局树

.
└── MaterialApp
    └── MyScaffold
        └── Scaffold
            └── AdaptiveLayout
                └── SlotLayout
                    └── MyPage
                        └── Scaffold
                            └── // ...

补充说明

之前我遇到过类似的页面过渡异常问题,通过重构代码解决了。我原本认为Scaffold需要作为Navigator的直接子组件才能让页面过渡正常工作,当前代码应该符合这个要求,但还是出现了过渡故障。


解决方案

试试下面几种方法解决黑色边框问题:

1. 去掉嵌套的Scaffold

布局里叠了两层Scaffold,容易引发渲染异常。把MyPage里的Scaffold删掉,直接返回内容容器:

class MyPage extends StatelessWidget {
  const MyPage({super.key});
  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final t = AppLocalizations.of(context)!;
    return Container(
      color: theme.colorScheme.background,
      constraints: const BoxConstraints.expand(),
      child: Text(t.myPageLabel),
    );
  }
}

2. 给包裹容器加背景色

Web端默认背景是黑色,动画过程中容器透明的话会透出底层颜色。给MyScaffold里的Container设置和页面一致的背景色:

builder: (_) => Container(
  clipBehavior: Clip.hardEdge,
  decoration: BoxDecoration(
    color: Theme.of(context).colorScheme.background,
  ),
  constraints: const BoxConstraints.expand(),
  child: child,
),

3. 调整Clip属性

Clip.hardEdge在Web端缩放时可能导致边缘渲染出问题,要么改成Clip.none,要么直接删掉这个属性:

builder: (_) => Container(
  // clipBehavior: Clip.hardEdge, 删掉或改成 Clip.none
  decoration: const BoxDecoration(),
  constraints: const BoxConstraints.expand(),
  child: child,
),

4. 自定义过渡动画

如果上面的方法都没用,直接自定义GoRouter的页面过渡,显式给动画层加背景色:

GoRoute(
  path: // ...
  pageBuilder: (context, state) => CustomTransitionPage(
    child: const MyPage(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      return ScaleTransition(
        scale: animation.drive(
          Tween(begin: 0.8, end: 1.0).chain(CurveTween(curve: Curves.easeInOut)),
        ),
        child: Container(
          color: Theme.of(context).colorScheme.background,
          child: child,
        ),
      );
    },
  ),
);

内容的提问来源于stack exchange,提问作者Felix ZY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:25:14