I am trying to write a custom ThemeData which I can pass to the extensions property of the ThemeData and be able to access them easily in my project. I have attached below the minimal code of what I am trying to achieve. As in the example code below, I want to be able to apply the theme simply by assigning to the style property as style: MyCustomAppTheme.of(context).specialTextStyle . The code below contains all the files of my minimal project: main.dart, theme.dart and my_custom_themedata.dart .
The problem: So, far I have not been able to override the lerp() (linear interpolation) method properly. Also there is a problem with my extending of the ThemeData class.
Codes:
main.dart:
import 'package:extending_flutter_themedata/themes/theme.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: MyCustomAppTheme.lightTheme,
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: const Text("Extending ThemeData"),
),
body: Text(
"Hello world",
style: MyCustomAppTheme.of(context).specialTextStyle,
),
);
}
}
theme.dart:
import 'package:extending_flutter_themedata/themes/extending_themedata/my_custom_themedata.dart';
import 'package:flutter/material.dart';
class MyCustomAppTheme {
MyCustomAppTheme._();
static ThemeData lightTheme = ThemeData(
useMaterial3: true,
fontFamily: "Roboto",
brightness: Brightness.light,
extensions: <ThemeExtension<dynamic>>[
MyCustomThemeData(
customBackgroundColor: Colors.pink,
specialTextStyle: const TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
],
);
}
my_custom_themedata.dart:
import 'package:flutter/material.dart';
class MyCustomThemeData extends ThemeExtension<MyCustomThemeData> {
final Color customBackgroundColor;
final TextStyle specialTextStyle;
MyCustomThemeData({
this.customBackgroundColor = Colors.blue,
this.specialTextStyle = const TextStyle(),
});
@override
MyCustomThemeData copyWith({
Color? customBackgroundColor,
TextStyle? specialTextStyle,
}) {
return MyCustomThemeData(
customBackgroundColor:
customBackgroundColor ?? this.customBackgroundColor,
specialTextStyle: specialTextStyle ?? this.specialTextStyle,
);
}
static MyCustomThemeData of(BuildContext context) {
return Theme.of(context).extension<MyCustomThemeData>()!;
}
@override
MyCustomThemeData lerp(MyCustomThemeData? a, MyCustomThemeData? b, double t) {
if (a == null) return b!;
if (b == null) return a;
return MyCustomThemeData(
customBackgroundColor:
Color.lerp(a.customBackgroundColor, b.customBackgroundColor, t)!,
specialTextStyle:
TextStyle.lerp(a.specialTextStyle, b.specialTextStyle, t)!,
);
}
static const id = 'my_custom_theme_data';
}
extension ThemeDataExtension on ThemeData {
MyCustomThemeData? get myCustomThemeData => extension<MyCustomThemeData>();
ThemeData copyWithCustom({MyCustomThemeData? myCustomThemeData}) {
return copyWith(
extensions: <ThemeExtension<dynamic>>{
if (myCustomThemeData != null) myCustomThemeData,
},
);
}
static ThemeData lerp(ThemeData? a, ThemeData? b, double t) {
return ThemeData.lerp(a, b, t)?.copyWithCustom(
myCustomThemeData: MyCustomThemeData.lerp(
a?.extension<MyCustomThemeData>(),
b?.extension<MyCustomThemeData>(),
t,
),
);
}
}
Update 01:
I have changes the lerp override to as follows and now some problems have resolved.
@override
MyCustomThemeData lerp(ThemeExtension<MyCustomThemeData>? other, double t) {
if (other is! MyCustomThemeData) {
return this;
}
return MyCustomThemeData(
customBackgroundColor:
Color.lerp(customBackgroundColor, other.customBackgroundColor, t)!,
specialTextStyle:
TextStyle.lerp(specialTextStyle, other.specialTextStyle, t)!,
);
}
Now, I am able to apply the theme as:
Text(
"Hello world",
style: MyCustomThemeData.of(context).specialTextStyle,
),
and the theme dos apply. But how can I access them using the following code within the build() method? (The Theme.of(context) method of access is still not working!)
MyCustomAppTheme? mcat = Theme.of(context).extension<MyCustomAppTheme>();
TextStyle myTextStyle = mcat.specialTextStyle;