我有一个
Slide
类,其子类指的是不同类型的幻灯片(IntroSlide
、SummarySlide
等):
abstract class Slide {
String slideType;
final String title;
final String voiceover;
final String? bgImage;
final List<SlideContent> content;
}
class SlideContent {
final String title;
final String description;
final String? image;
SlideContent({
required this.title,
required this.description,
this.image,
});
}
// class IntroSlide extends Slide...
// class SummarySlide extends Slide...
有些幻灯片不会有
bgImage
或 image
中的 SlideContent
,但有的幻灯片会根据要求有。
即使所有子类都有相同的字段,每个子类都有自己的视图/表示,其中字段将以自己独特的方式使用。
现在我的问题是,为了让子类在调用时返回一个小部件,它们需要扩展
StatelessWidget
或 StatefulWidget
,但我不想为我添加的新幻灯片类型声明所有公共字段(IntroSlide、 SummarySlide 等),我已经在 Slide
抽象类中声明了它,但我还必须返回一个小部件。我该如何解决这个问题?
由于
Slide
的子类应该是StatelessWidget
或StatefulWidget
,我建议将Slide
作为Widget
的子类。当定义 Slide
的子类时,您可以根据需要 implement StatelessWidget
或 StatefulWiget
。
下面的示例可以粘贴到dartpad中。为了简单起见,我减少了小部件参数的数量:
import 'package:flutter/material.dart';
abstract class Slide extends Widget {
const Slide({
super.key,
required this.title,
});
final String title;
}
class IntroSlide extends Slide implements StatelessWidget {
const IntroSlide({
super.key,
required super.title,
});
@override
Widget build(BuildContext context) {
return Text(title);
}
@override
StatelessElement createElement() => StatelessElement(this);
}
class SummarySlide extends Slide implements StatefulWidget {
const SummarySlide({
super.key,
required super.title,
});
@override
StatefulElement createElement() => StatefulElement(this);
@override
State<StatefulWidget> createState() {
return BlogSlideState();
}
}
class BlogSlideState extends State<SummarySlide> {
Widget build(BuildContext context) {
return Text(widget.title);
}
}
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Slide Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: Colors.blue,
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({
super.key,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Slide Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IntroSlide(title: 'IntroSlide'),
SummarySlide(title: 'SummarySlide'),
],
),
),
);
}
}