Offstage 与 Visibility 都是用来控制显隐的,让人感觉很简单,但还是有一些细节需要注意的。
Offstage 一定会让 child 执行 layout
void performLayout() {
if (offstage) {
child?.layout(constraints);
} else {
super.performLayout();
}
}
Offstage 这样处理有好处还有坏处。好处是可以平滑的切换显隐,保持 state;坏处是会浪费一点性能。知道了这个特性后,也可以利用这一点做出更好的体验。
Offstage 会透传 constrains 给 child。在显示的时候, size 与 child 相同,在不显示的时候,size 为 0。
Visibility 是显隐的集大成者
只是控制显隐
Visibility(
visible: true,
child: Text('IAM17')
)
如果只是简单的控制显隐的话,Visibility 的逻辑非常简单。只需要 visible 参数就可以,显示就返回 child,不显示返回占位的 widget。
return visible ? child : replacement;
Visibility 在不显示的时候可以显示 replacement,这一点是 Offstage 无法做到的。如果不显示 child,会完全不执行 child 的逻辑,效率会更高。
保持 state
只需要 maintainState 为 true 即可。
Visibility(
visible: true,
maintainState:true,
child: Text('IAM17')
)
保持 state 的逻辑处理是这样的,默认会停掉动画,用 Offstage 控制显隐。
if (maintainState) {
Widget result = child;
if (!maintainAnimation) {
result = TickerMode(enabled: visible, child: child);
}
return Offstage(
offstage: !visible,
child: result,
);
}
保持 state 同时保持动画
在操持 state 的基础上 ,maintainAnimation 也为true,就可以保持动画了。
Visibility(Ï
visible: true,
maintainState: true,
maintainAnimation: true,
child: Text('IAM17')
)
保持 size
保持 size 的时候 ,返回了 Opacity,通过控制透明度来控制显隐。
所以保持 size 需要 maintainSize,maintainAnimation,maintainState 同时为 true。
Visibility(
visible: true,
maintainSize: true,
maintainAnimation: true,
maintainState:true,
child: Text('IAM17')
)
保持交互
保持交互的要求最高了,在保持 size 的基础上加上 maintainInteractivity 为 true。
Visibility(
visible: true,
maintainSize: true,
maintainAnimation: true,
maintainState: true,
maintainInteractivity: true,
child: Text('IAM17')
)
保持交互虽然用到的参数多,但也不用担心麻烦,因为用到的机会实在有限:都已经看不见了?还有交互的需求吗?
总结
Offstage 与 Visibility 都有控制显隐的功能,显然 Visibility 的功能更全面,一般来说,直接用 Visibility 就好。
虽然也可以用其它组件也可以达到控制显隐的效果,但最好是用这两个组件,因为这样可读性最好。