I have a Slide
class with subclasses referring to the different types of slides (IntroSlide
, SummarySlide
, etc.):
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...
Some slides will not have bgImage
or the image
in SlideContent
but those who do will have them as required.
Even though all subclasses have the same fields, each subclass will have its own view/presentation where the fields will be used in their own unique fashion.
Now my question is, for the subclasses to return a widget when called, they need to extend off of StatelessWidget
or StatefulWidget
, but I dont want to declare all the common fields for the new slide types I add (IntroSlide, SummarySlide etc) which I have already declared in the Slide
abstract class, but I also must return a widget. How should I approach this problem?
Since the sub-classes of Slide
should be either a StatelessWidget
or a StatefulWidget
, I would suggest making Slide
a subclass of Widget
. When defining the sub-classes of Slide
you could then implement StatelessWidget
or StatefulWiget
as required.
The example below can be pasted into a dartpad. For the sake of simplicity, I reduced the number of widget parameters:
import 'package:flutter/material.dart';
abstract class Slide extends Widget {
const Slide({
super.key,
required this.title,
// ... additional parameters.
});
final String title;
// ... additional class variables.
}
class IntroSlide extends Slide implements StatelessWidget {
const IntroSlide({
super.key,
required super.title,
});
@override
Widget build(BuildContext context) {
return Text(title); // <---- Build your custom widget here.
}
@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); // <--- Build you custom stateful widget here.
}
}
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'),
],
),
),
);
}
}