面试题答案
一键面试利用Navigator结合动画效果实现流畅页面切换及优化资源加载
- 使用PageRouteBuilder实现动画
PageRouteBuilder
允许自定义过渡动画。例如,实现一个淡入淡出的动画:
Navigator.push( context, PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) => TargetPage(), transitionsBuilder: (context, animation, secondaryAnimation, child) { var begin = Offset(0.0, 1.0); var end = Offset.zero; var curve = Curves.ease; var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); return SlideTransition( position: animation.drive(tween), child: child, ); }, ), );
- 预加载资源
- 在进入新页面之前,可以提前加载一些必要的资源。例如,如果新页面需要加载图片,可以使用
precacheImage
方法。
final image = Image.asset('assets/image.png'); precacheImage(image.image, context); Navigator.push(context, MaterialPageRoute(builder: (context) => TargetPage()));
- 在进入新页面之前,可以提前加载一些必要的资源。例如,如果新页面需要加载图片,可以使用
- 减少白屏时间
- 懒加载:对于一些非关键的UI组件或数据,可以采用懒加载的方式。例如,使用
FutureBuilder
来异步加载数据,并在数据加载完成后显示。
FutureBuilder( future: _fetchData(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return CircularProgressIndicator(); } else if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } else { return Text('Data: ${snapshot.data}'); } }, );
- 占位符:在加载资源时,先显示占位符。例如,对于图片,可以先显示一个灰色的矩形占位,待图片加载完成后再替换。
- 懒加载:对于一些非关键的UI组件或数据,可以采用懒加载的方式。例如,使用
在不同平台上定制Navigator的过渡动画
- iOS平台
- 在
CupertinoPageRoute
基础上进行定制。CupertinoPageRoute
是iOS风格的页面路由。例如,要实现类似iOS原生的从右向左滑动返回动画,可以这样:
Navigator.push( context, CupertinoPageRoute( builder: (context) => TargetPage(), transitionDuration: const Duration(milliseconds: 300), reverseTransitionDuration: const Duration(milliseconds: 300), ), );
- 若要进一步定制,可以继承
CupertinoPageRoute
并重写buildTransitions
方法。
- 在
- Android平台
- 对于Android平台,默认的
MaterialPageRoute
已经符合Android平台风格。若要定制,可以同样继承MaterialPageRoute
并重写buildTransitions
方法。例如,改变动画时长:
class CustomMaterialPageRoute extends MaterialPageRoute { CustomMaterialPageRoute({WidgetBuilder builder, RouteSettings settings}) : super(builder: builder, settings: settings); @override Duration get transitionDuration => const Duration(milliseconds: 500); }
- 然后使用自定义的路由:
Navigator.push( context, CustomMaterialPageRoute(builder: (context) => TargetPage()), );
- 对于Android平台,默认的