由于 Dart/Flutter 使用组合风格的方法来构建小部件(将其与作用域模型的操作方式相结合),开发封装小部件的对象库的良好模式是什么?
假设您有一个应用程序,允许您在 ListView 中显示对象列表,每个对象都有自己的方式来显示它们的信息,但都采用相同的方法来实现。
考虑以下伪代码,它采用封装所有必需的小部件和每个对象所需的其他此类属性/方法的方法。
abstract class Vehicle {
int type;
String name;
Widget listWidget
Widget editWidget
Widget settingsWidget
}
class Truck extends Vehicle {
type = 1
name = "Truck"
listWidget = ... My truck widget for within lists...
editWidget = ... My truck edit widget ...
settingsWidget = ... My truck settings display ...
}
class Car extends Vehicle {
type = 1
name = "Car"
listWidget = ... My car widget for within lists...
editWidget = ... My car edit widget ...
settingsWidget = ... My car settings display ...
}
使用这种方法,我将不得不创建每种车辆类型并遵循抽象的 api 模式,而不用担心它是如何呈现的。
当谈到在列表(例如 ListView)中显示车辆时,这种方法允许对象本身决定它在该列表中的呈现方式,并且它对于每种类型的车辆可能是唯一的。
例如:
Container(
child: new ListView.builder(
itemCount: items.length,
itemBuilder: (BuildContext ctxt, int index) {
return items[index].listWidget;
}
)
)
这是实现此目的的有效 Dart/Flutter 方法还是应该遵循更好的模式?
我是否违反了 Dart 推荐的编码模式,因为每个小部件都会控制它自己的显示?
这背后的想法是,如果需要根据车辆类型对设置面板进行不同的格式化,我可以做到,而不是试图弄清楚如何为所有小部件创建通用的显示模式。
想法?
最佳答案
我想你真正想要的是这样的东西,我将使用 Flutter Dart 代码而不是伪代码:
class Vehicle extends StatelessWidget {
final int type;
final String name;
final Widget list, edit, settings;
const Vehicle({Key key, this.type, this.name, this.list, this.edit, this.settings}) : super(key: key);
@override
Widget build(BuildContext context) => Row(children: <Widget>[list, edit, settings]);
}
class Truck extends StatelessWidget {
const Truck({Key key}) : super(key: key);
@override
Widget build(BuildContext context) => Vehicle(
type: 1,
name: 'Truck',
list: Column(),
edit: const Icon(Icons.edit),
settings: Checkbox(),
);
}
class Car extends StatelessWidget {
const Car({Key key}) : super(key: key);
@override
Widget build(BuildContext context) => Vehicle(
type: 2,
name: 'Car',
list: Column(),
edit: const Icon(Icons.edit_location),
settings: ToggleButtons(...),
);
}
如您所见,您可以拥有一个预定义的 Vehicle
类,它定义参数并处理布置您想要为不同车辆动态显示的所有信息。
现在,您可以通过创建另一个在其构建方法中返回 Vehicle
的小部件来实现特定的车辆。
显然,我选择的布局小部件Row
、Column
等只是作为占位符,但您实际上可以使用这种方法实现您的布局逻辑。
我会说这是一种更惯用的小部件方法。
关于您的示例:在使用 ListView.builder
时,您可能不应该将小部件存储在 List
中,但您可以在 builder< 中动态实例化您的小部件
功能。如果您可以使用 ListView.builder
,这在性能方面也会更好。如果你不能动态创建你的项目,你可以使用 ListView
而是将您的小部件存储在列表中。
builder: () {
if (items[index]['type'] == 'car')
return Car(...);
return Truck(...);
}
关于design-patterns - 如何定义抽象小部件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58632550/