I want to create a universal alert that I will use several times in my app.
class SelectIconAlertDialogWidget extends StatelessWidget {
const SelectIconAlertDialogWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final model = Provider.of<IncomeViewModel>(context, listen: true).state;
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
Problem is that I can not figure out how to pass type of parent ChangeNotifier
showDialog<String>(
context: context,
builder: (_) =>
ChangeNotifierProvider<IncomeViewModel>.value(
value: view,
child: const SelectIconAlertDialogWidget(),
),
);
I have a lot of ViewModels that will use this alert so dont want to repeat this code and write generic Alert that I can use with any ViewModel. How can I achieve this?
Create some abstract class with methods or fields you want to have for all your view models you use for that dialog
abstract class AbstractViewModel{
void doStuff();
}
Implement this class for your view models
class MyViewModel1 implements AbstractViewModel{
@override
void doStuff (){ print("from MyViewModel1");}
}
Add type parameter for your dialog class
class SelectIconAlertDialogWidget<T extends AbstractViewModel> extends StatelessWidget {
const SelectIconAlertDialogWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// and you can use generic type T like this:
final model = Provider.of<T>(context, listen: true);
model.doStuff();
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
And call it passing type parameter SelectIconAlertDialogWidget<MyViewModel1>()
showDialog<String>(
context: context,
builder: (_) =>
ChangeNotifierProvider<MyViewModel1>.value(
value: view,
child: const SelectIconAlertDialogWidget<MyViewModel1>(),
),
);
On build method of your dialog widget it will print "from MyViewModel1". Hope you got the concept of abstraction.