1. 程式人生 > >Flutter 1.17 新 Material motion 規範的預構建動畫

Flutter 1.17 新 Material motion 規範的預構建動畫

![](https://img2020.cnblogs.com/other/467322/202007/467322-20200709202332478-1547042811.png) > 老孟導讀:在 Flutter 1.17 釋出大會上,Flutter 團隊還發布了新的 Animations 軟體包,該軟體包提供了實現新的 Material motion 規範的預構建動畫。 軟體包 pub 地址:[https://pub.dev/packages/animations](https://pub.dev/packages/animations) Material motion 規範:[https://material.io/design/motion/the-motion-system.html](https://material.io/design/motion/the-motion-system.html) 引入外掛,版本號請到 pub 上檢視最新版本號: ``` animations: ^1.1.1 ``` ### Container transform 容器轉換模式設計用於包含容器的UI元素之間的轉換。此模式在兩個UI元素之間建立可見連線。 案例:構建GridView,點選其中一項時跳轉到期詳情頁面: ```dart GridView.builder( padding: EdgeInsets.all(8), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 2, mainAxisSpacing: 4), itemBuilder: (context, index) { return OpenContainer( transitionDuration: _duration, closedBuilder: (BuildContext _, VoidCallback openContainer) { return Container( child: Image.asset( 'assets/images/b.jpg', fit: BoxFit.fitWidth, ), ); }, openBuilder: (BuildContext context, VoidCallback _) { return _DetailPage(); }, ); }, itemCount: 50, ) ``` 使用 **OpenContainer** 元件,closedBuilder 表示關閉狀態時到元件,在這裡表示 GridView Item,openBuilder 表示點選要跳轉的頁面,這裡表示詳情頁面。 詳情頁面程式碼如下: ```dart class _DetailPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Container( width: double.infinity, height: double.infinity, child: Image.asset( 'assets/images/b.jpg', fit: BoxFit.cover, ), ), ); } } ``` ![](https://img2020.cnblogs.com/other/467322/202007/467322-20200709202335244-779521752.gif) 構建ListView ```dart ListView.builder( itemBuilder: (context, index) { return OpenContainer( transitionDuration: _duration, closedBuilder: (BuildContext _, VoidCallback openContainer) { return Card( child: Container( height: 45, alignment: Alignment.center, child: Text('$index'), ), ); }, openBuilder: (BuildContext context, VoidCallback _) { return _DetailPage(); }, ); }, itemCount: 50, ) ``` ![](https://img2020.cnblogs.com/other/467322/202007/467322-20200709202338464-1120373362.gif) 也可以是一個按鈕,比如 floatingActionButton ```dart Scaffold( body: _buildListView(), floatingActionButton: OpenContainer( openBuilder: (BuildContext context, VoidCallback _) { return _DetailPage(); }, transitionDuration: _duration, closedElevation: 6.0, closedShape: const RoundedRectangleBorder( borderRadius: BorderRadius.all( Radius.circular(50), ), ), closedColor: Theme.of(context).colorScheme.secondary, closedBuilder: (BuildContext context, VoidCallback openContainer) { return SizedBox( height: 50, width: 50, child: Center( child: Icon( Icons.add, color: Theme.of(context).colorScheme.onSecondary, ), ), ); }, ), ) ``` ![](https://img2020.cnblogs.com/other/467322/202007/467322-20200709202339936-624710087.gif) 頂部輸入框 ```dart Scaffold( appBar: AppBar( title: OpenContainer( transitionDuration: _duration, closedBuilder: (BuildContext _, VoidCallback openContainer) { return Container( width: 300, height: 45, padding: EdgeInsets.only(left: 5), decoration: BoxDecoration( border: Border.all(color: Colors.grey.withOpacity(.5))), alignment: Alignment.centerLeft, child: Icon(Icons.search,color: Colors.black,), ); }, openBuilder: (BuildContext context, VoidCallback _) { return _DetailPage(); }, ), ), ) ``` ![](https://img2020.cnblogs.com/other/467322/202007/467322-20200709202342966-1950636002.gif) ### Shared axis 共享軸模式用於具有空間或導航關係的UI元素之間的過渡。此模式在x,y或z軸上使用共享的變換來加強元素之間的關係。 底部導航案例: ```dart @override Widget build(BuildContext context) { Widget _child = _OnePage(); switch (_currentIndex) { case 1: _child = _TwoPage(); break; } return Scaffold( body: PageTransitionSwitcher( duration: const Duration(milliseconds: 1500), reverse: false, transitionBuilder: ( Widget child, Animation