对于导航,我构建了一个简单的工厂类,该类生成一个ListTile,将ListPile推送到导航器:
static Widget simpleNavRow(String text, BuildContext context, String route) {
return Column(
children: <Widget>[
ListTile(
title: Text(text),
onTap: () {
Navigator.pushNamed(context, route);
},
),
Divider(),
],
);
}
但是,我很快意识到,支持推送小部件也很方便(如果可能的话,也可以从其类中实例化)。我不知道如何使“ route”参数接受字符串或小部件,因此我创建了一个用这两种类型之一初始化的类。这段代码有效,但是有更好的方法实现吗?
class NavTo {
String route;
Widget widget;
NavTo.route(this.route);
NavTo.widget(this.widget);
push(BuildContext context) {
if (route != null) {
Navigator.pushNamed(context, route);
}
if (widget != null) {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return widget;
}));
}
}
}
class ListHelper {
static final padding = EdgeInsets.all(12.0);
static Widget simpleNavRow(String text, BuildContext context, NavTo navTo) {
return Column(
children: <Widget>[
ListTile(
title: Text(text),
onTap: () {
navTo.push(context);
},
),
Divider(),
],
);
}
}
// usage:
// ListHelper.simpleNavRow('MyWidget', context, NavTo.widget(MyWidget()))
答案 0 :(得分:1)
由于您期望使用多种类型之一,因此,先拥有dynamic
,然后在NavTo的push方法中,您可以检查类型:
class NavTo {
dynamic route;
push(BuildContext context) {
if (route is String) {
...
} else if (route is Widget) {
...
}
}
}
答案 1 :(得分:1)
我不认为Dart中提供联合类型。我喜欢您的解决方案,而不是使用动态类型,因为它是强类型的。 您可以使用命名参数。
NavTo({this.route,this.widget})
但是您就不必对一个参数和一个参数进行编译类型检查了。
我对构造函数的唯一改进是添加@required
。
答案 2 :(得分:1)
我个人希望为Items提供MaterialPageRoute参数
static Widget simpleNavRow(String text, BuildContext context, MaterialPageRoute route) {
return Column(
children: <Widget>[
ListTile(
title: Text(text),
onTap: () {
Navigator.push(context, route);
},
),
Divider(),
],);
}
像这样保持沉默的项目,我决定它们在父母中做什么。 您可以为每种类型创建商品工厂之后,就可以像这样初始化正确的路线:
class ItemExemple extends StatelessWidget {
final String text;
final MaterialPageRoute route;
ItemExemple(this.text, this.route);
factory ItemExemple.typeA(String text, BuildContext context) =>
new ItemExemple(text, new MaterialPageRoute(builder: (context) => new ItemA()));
factory ItemExemple.typeB(String text, BuildContext context) =>
new ItemExemple(text, new MaterialPageRoute(builder: (context) => new ItemB()));
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListTile(
title: Text(this.text),
onTap: () {
Navigator.push(context, route);
},
),
Divider(),
],);
}
}