Flutter 很大一个特点就是 Android 和 iOS 两平台一套代码,但是随着 Flutter 越发精准实现两平台的特色,各种控件差异度越来越大。如: NavigationBar, Button, Scaffold。官方在 Flutter 1.7 给出了解决方案 PlatformWidget。
/// A simple widget that builds different things on different platforms.
class PlatformWidget extends StatelessWidget {
const PlatformWidget({
Key key,
@required this.androidBuilder,
@required this.iosBuilder,
}) : assert(androidBuilder != null),
assert(iosBuilder != null),
super(key: key);
final WidgetBuilder androidBuilder;
final WidgetBuilder iosBuilder;
@override
Widget build(context) {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return androidBuilder(context);
case TargetPlatform.iOS:
return iosBuilder(context);
default:
assert(false, 'Unexpected platform $defaultTargetPlatform');
return null;
}
}
}
然后在业务中出现分叉
@override
Widget build(context) {
return PlatformWidget(
androidBuilder: _buildAndroid,
iosBuilder: _buildIos,
);
}
Widget _buildAndroid(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(song)),
body: _buildBody(),
);
}
Widget _buildIos(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(song),
previousPageTitle: 'Songs',
),
child: _buildBody(),
);
}
_buildBody 里才是两平台相同的代码。
平台定义为:
enum TargetPlatform {
/// Android: <https://www.android.com/>
android,
/// Fuchsia: <https://fuchsia.googlesource.com/>
fuchsia,
/// iOS: <http://www.apple.com/ios/>
iOS,
}
这种方式固然解决了问题,但是个人建议:不用管平台的设计差异,实现适合用户操作的混合风格 App 就好。譬如安卓的右滑回退是不推荐的,个人感觉极不方便,改用统一的 iOS 风格会方便操作。其次类似 iOS 风格的按钮等,直接用 Materialed Button 即可。这样能省去无数麻烦,毕竟代码简洁、用户操作方便。App 的风格是否完全符合平台特色不是重点。
Flutter 做动画等特色难度大为降低,可以在这个方向下点功夫让 App 更加精美。