平時咱們在切換 Widget 的時候是怎樣的呢?html
有沒有動畫效果?是否是直接改變了一個 Widget?git
相似於這樣的:github
若是是的話,那麼今天所說的 Widget,絕對符合你的口味。api
那如何在 Flutter 當中切換 Widget 的時候加上特效?完成這樣的效果?app
AnimatedSwitcher
瞭解一下。ide
話很少說,功能咱們已經瞭解,再來看一下官方的介紹:函數
A widget that by default does a FadeTransition between a new widget and the widget previously set on the AnimatedSwitcher as a child.動畫
If they are swapped fast enough (i.e. before duration elapses), more than one previous child can exist and be transitioning out while the newest one is transitioning in.ui
If the "new" child is the same widget type and key as the "old" child, but with different parameters, then AnimatedSwitcher will not do a transition between them, since as far as the framework is concerned, they are the same widget and the existing widget can be updated with the new parameters. To force the transition to occur, set a Key on each child widget that you wish to be considered unique (typically a ValueKey on the widget data that distinguishes this child from the others).this
大體意思就是:
默認狀況下是執行透明度的動畫。
若是交換速度足夠快,則存在多個子級,可是在新子級傳入的時候將它移除。
若是新 Widget 和 舊 Widget 的類型和鍵相同,可是參數不一樣,那麼也不會進行轉換。若是想要進行轉換,那麼要添加一個 Key。
再來看構造函數,來肯定如何使用:
const AnimatedSwitcher({
Key key,
this.child,
@required this.duration,
this.reverseDuration,
this.switchInCurve = Curves.linear,
this.switchOutCurve = Curves.linear,
this.transitionBuilder = AnimatedSwitcher.defaultTransitionBuilder,
this.layoutBuilder = AnimatedSwitcher.defaultLayoutBuilder,
}) : assert(duration != null),
assert(switchInCurve != null),
assert(switchOutCurve != null),
assert(transitionBuilder != null),
assert(layoutBuilder != null),
super(key: key);
複製代碼
來解釋一下每一個參數:
其中必要參數就是一個 duration
,那既然知道如何使用了,那就開擼。
前面咱們看的圖,就是在對 AppBar
上的 actions
進行操做,
其實這個例子在實際開發當中常常存在,確定要刪除一些東西的嘛,而後選中了之後批量刪除。
那這裏也很少說,直接上代碼,而後解釋:
class _AnimatedSwitcherPageState extends State<AnimatedSwitcherPage> {
IconData _actionIcon = Icons.delete;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AnimatedSwitcherPage'),
actions: <Widget>[
AnimatedSwitcher(
transitionBuilder: (child, anim){
return ScaleTransition(child: child,scale: anim);
},
duration: Duration(milliseconds: 300),
child: IconButton(
key: ValueKey(_actionIcon),
icon: Icon(_actionIcon),
onPressed: () {
setState(() {
if (_actionIcon == Icons.delete)
_actionIcon = Icons.done;
else
_actionIcon = Icons.delete;
});
}),
)
],
),
body: Container());
}
}
複製代碼
咱們定義的是一個 StatefulWidget
,由於在切換 Widget 的時候要調用 setState()
,
下面來講一下整個流程:
Icons.delete
AppBar
的 actions
裏面加入 AnimatedSwitcher
transitionBuilder
爲 縮放動畫 ScaleTransition
AnimatedSwitcher
的 child 爲 IconButton
IconButton
添加了一個 ValueKey
,值就爲定義好的 IconData
最後再看一下效果:
使用該控件最應該注意的點就是 Key 的問題,必定要記住:
若是新 Widget 和 舊 Widget 的類型和鍵相同,可是參數不一樣,那麼也不會進行轉換。若是想要進行轉換,那麼要添加一個 Key。
完整代碼已經傳至GitHub:github.com/wanglu1209/…