platty
Flutter 不会尝试为特定平台提供熟悉的控件(与 React Native、ionic 和其他跨平台工具不同)。这对于所有平台上的统一渲染、最大的灵活性以及消除为每个平台进行测试和调试的整个类别的问题具有巨大的好处。虽然这很棒,但在许多场景下我们希望我们的应用程序看起来和感觉都像 Android 或 iOS 应用程序。Platty 允许您通过最小的努力和最大的控制在一个统一的 API 中渲染类似 iOS(Cupertino)和 Android(Material)的控件。
不再需要在渲染块中检查平台以渲染 CupertinoButton 或 FlatButton,让 platty 为您处理逻辑!想在您的应用程序中使用底部标签页,这些标签页会解析为特定于平台的 UI?没问题!
入门
使用 platty 来统一渲染特定于平台的 API。该库利用 BuildContext 主题 API 将平台
信息传播到 Widgets。
默认情况下,所有小部件都符合默认的 TargetPlatform。它会查找其默认的 Theme.of(context).platform。
同样,所有小部件都提供一个 renderPlatform 属性,允许您选择要渲染的那个(如果您愿意)。
将 MaterialApp 和 CupertinoApp 替换为 PlatformApp
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return PlatformApp(
title: 'Flutter Demo',
// specify our app theme here. We do the leg work of bridging it to Cupertino.
unifiedTheme: ThemeData(
primarySwatch: Colors.lightBlue,
bottomAppBarColor: Colors.red,
),
home: ExamplePage(),
);
}
}
PlatformApp 统一了 MaterialApp 和 CupertinoApp 之间的所有相同属性,以便在层次结构中同时存在这两种小部件实例,并
根据平台切换样式。
现在,您可以用我们库中包含的 "P" 对应物替换小部件
Button/CupertinoButton -> PButton


FlatButton/CupertinoButton -> PFlatButton


AppBar/CupertinoNavigationBar -> PNavigationBar


SliverAppBar/CupertinoSliverNavigationBar -> PSliverNavigationBar
Slider/CupertinoSlider -> PSlider

Switch/CupertinoSwitch -> PSwitch

BottomNavigationBar/CupertinoTabBar -> PTabBar


Scaffold/CupertinoScaffold -> PScaffold
CircularProgressIndicator/CupertinoActivityIndicator -> PActivityIndicator

BackButton/CupertinoNavigationBarBackButton -> PBackButton
AlertDialog/CupertinoAlertDialog -> PAlertDialog

特定于平台的属性带有前缀
任何具有 iOS 特定或 Android 特定对应项的小部件,它们会相应地被加上 android/ios 前缀
例如,PButton 的 androidShape 适用于 RaisedButton.shape 属性。在 CupertinoButton 上不存在。
但是 CupertinoButton 有一个 borderRadius 和 pressedOpacity。这两个属性变成了 iosBorderRadius 和 iosPressedOpacity。
助手
此库捆绑了一些标准函数,可以轻松返回特定于平台的代码。而不是检查
并切换 Theme.of(context).targetPlatform 的结果,请使用以下方法
特定平台实例
要让特定的 P-Widget 只使用特定的平台主题,例如 Material 或 Cupertino,您可以将其包装在PTheme 实例中
PTheme(
data: PThemeData(
platform: TargetPlatform.android, // or iOS
child: child,
),
);
或者,更简单地,使用助手方法
PTheme.ios(child);
PTheme.android(child);
同样,所有 P-Widgets 和方法都允许您使用构造函数中的 renderPlatform 参数来覆盖 PTheme
或调用方法
PButton("Hello Android",
renderPlatform: TargetPlatform.Android,
)
这将把渲染切换到此特定小部件的 Material 小部件。
注意:使用 PTheme 包装小部件会将该实例传播到小部件的层次结构中,因此比
为每个单独的小部件手动指定 renderPlatform 效果更好。
创建您自己的平台适应性小部件
我们可以扩展此库中包含的逻辑来构建我们自己强大的平台适应性小部件。
库中包含 PlatformAdaptingWidget 基类,它继承自 StatelessWidget。
class SamplePlatformWidget extends PlatformAdaptingWidget {
final Color color;
SamplePlatformWidget({Key key, @required this.color, TargetPlatform renderPlatform}) // should allow consumers to choose TargetPlatform
: super(key: key, renderPlatform: renderPlatform);
/// Render a material widget here. Most Material widgets require a Material Theme instance above it.
@override
get renderMaterial => (BuildContext context) {
return BackButton(
color: color,
);
};
/// Render a cupertino widget here.
@override
get renderCupertino => (BuildContext context) {
return CupertinoNavigationBarBackButton(
color: color,
);
};
/// Render a fuchsia widget here. (defaults to material)
@override
get renderFuchsia => (BuildContext context) {
return BackButton(
color: color,
);
};
}
平台特定的逻辑
此库提供了几种实现基于平台行为的标准方法。
您可以使用 platformWrap,它允许您指定一个 child,并在 1 个或所有平台上将其包装
在另一个小部件中
platformWrap(
context,
child: PButton(
padding: EdgeInsets.all(0.0),
child: Text(title),
color: Colors.red,
onPressed: () {
Navigator.push(context, PlatformRoute.of(context, builder: page));
},
),
renderCupertino: (context, child) => Padding(
padding: EdgeInsets.only(bottom: 8.0),
child: child,
),
);
您可以指定 renderCupertino、renderMaterial 或 renderFuschia(或都不指定)。
任何未指定的渲染方法都默认为 child。
同样,platformSelect 是一个助手,它能够以统一的方式返回基于平台的不同对象。
在我们的 PlatformAdaptingWidget 中,我们使用它来根据平台返回不同的小部件。您可以使用它来返回任何
基于平台的返回类型
Column(
children: [
platformSelect(context,
renderMaterial: (context) => Text("I am android"),
renderCupertino: (context) => Text("I am iOS"),
renderFuchsia: (context) => Text("I am FUCHSIA"))
],
),
renderMaterial 和 renderCupertino 是必需的。renderFuchsia 默认为 material。
或者您可以返回非小部件
Column(
children: [
Text(platformSelect(context,
renderMaterial: (context) => "I am android"),
renderCupertino: (context) => "I am iOS",
renderFuchsia: (context) => "I am FUCHSIA"))
],
),