有没有更好的方法在 Flutter 中编写这段代码?
Is there a better way to write this code in Flutter?
我知道我可以应用 switch-case 运算符,但我认为看起来还是有点冗长。基本上是包裹在 Widget 中的动态值列表,returns BaseItemWidget 到 ListView。
列表如下:
class MyListView extends StatelessWidget {
const MyListView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ReorderableListView(
shrinkWrap: true,
onReorder: provider.reorderList,
children: provider.items.map((item) {
return Dismissible(
key: UniqueKey(),
direction: DismissDirection.none,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
BaseItemWidget(item),
const Divider(height: 0)
],
),
);
}).toList(),
);
}
}
这是该列表中的小部件:
class BaseItemWidget extends StatelessWidget {
final dynamic item;
const BaseItemWidget({Key? key, this.item}) : super(key: key);
@override
Widget build(BuildContext context) {
if (item is TextItem) {
return TextItemWidget(item);
} else if (item is EditableItem) {
return EditableItemWidget(item);
} else if (item is ImageItem) {
return ImageItemWidget(item);
} else if (item is BarcodeItem) {
return BarcodeItemWidget(item);
}
return const SpaceItemWidget();
}
}
所有小部件中的项目也是动态的。
你可以考虑让你的每个 XItem
classes 扩展一个抽象 BaseItem
class,它有一个 widget
构造正确的方法该项目的小部件。像这样:
abstract class BaseItem {
Widget widget();
}
class TextItem extends BaseItem {
@override
Widget widget() => TextItemWidget(this);
}
// Etc, for the other item types
class MyListView extends StatelessWidget {
const MyListView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ReorderableListView(
shrinkWrap: true,
onReorder: provider.reorderList,
children: provider.items.map((item) {
return Dismissible(
key: UniqueKey(),
direction: DismissDirection.none,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
item.widget(),
const Divider(height: 0)
],
),
);
}).toList(),
);
}
}
感谢@Michael Horn 的回答,结果如下:
class TextItem extends BaseItemWidget{
TextAlign align;
TicketLineColor color;
double size;
String text;
bool isBold;
bool isUnderlined;
TextItem({
this.size = 20,
this.text = '',
this.isBold = false,
this.isUnderlined = false,
this.align = TextAlign.left,
this.color = TicketLineColor.black,
});
PosText toPosText() {
final posText = PosText(
text: text,
isBold: isBold,
isUnderlined: isUnderlined,
posAlign: align.toPosAlign(),
posColor: color.toPosColor(),
);
return posText;
}
String generatePosString() => toPosText().toString();
@override
Widget widget() => TextItemWidget(this);
}
我知道我可以应用 switch-case 运算符,但我认为看起来还是有点冗长。基本上是包裹在 Widget 中的动态值列表,returns BaseItemWidget 到 ListView。
列表如下:
class MyListView extends StatelessWidget {
const MyListView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ReorderableListView(
shrinkWrap: true,
onReorder: provider.reorderList,
children: provider.items.map((item) {
return Dismissible(
key: UniqueKey(),
direction: DismissDirection.none,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
BaseItemWidget(item),
const Divider(height: 0)
],
),
);
}).toList(),
);
}
}
这是该列表中的小部件:
class BaseItemWidget extends StatelessWidget {
final dynamic item;
const BaseItemWidget({Key? key, this.item}) : super(key: key);
@override
Widget build(BuildContext context) {
if (item is TextItem) {
return TextItemWidget(item);
} else if (item is EditableItem) {
return EditableItemWidget(item);
} else if (item is ImageItem) {
return ImageItemWidget(item);
} else if (item is BarcodeItem) {
return BarcodeItemWidget(item);
}
return const SpaceItemWidget();
}
}
所有小部件中的项目也是动态的。
你可以考虑让你的每个 XItem
classes 扩展一个抽象 BaseItem
class,它有一个 widget
构造正确的方法该项目的小部件。像这样:
abstract class BaseItem {
Widget widget();
}
class TextItem extends BaseItem {
@override
Widget widget() => TextItemWidget(this);
}
// Etc, for the other item types
class MyListView extends StatelessWidget {
const MyListView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ReorderableListView(
shrinkWrap: true,
onReorder: provider.reorderList,
children: provider.items.map((item) {
return Dismissible(
key: UniqueKey(),
direction: DismissDirection.none,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
item.widget(),
const Divider(height: 0)
],
),
);
}).toList(),
);
}
}
感谢@Michael Horn 的回答,结果如下:
class TextItem extends BaseItemWidget{
TextAlign align;
TicketLineColor color;
double size;
String text;
bool isBold;
bool isUnderlined;
TextItem({
this.size = 20,
this.text = '',
this.isBold = false,
this.isUnderlined = false,
this.align = TextAlign.left,
this.color = TicketLineColor.black,
});
PosText toPosText() {
final posText = PosText(
text: text,
isBold: isBold,
isUnderlined: isUnderlined,
posAlign: align.toPosAlign(),
posColor: color.toPosColor(),
);
return posText;
}
String generatePosString() => toPosText().toString();
@override
Widget widget() => TextItemWidget(this);
}