页面切换时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
相关产品推荐
相关产品推荐

