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 就好。
虽然也可以用其它组件也可以达到控制显隐的效果,但最好是用这两个组件,因为这样可读性最好。