flutter_platform_widgets
flutter_platform_widgets copied to clipboard
Feature Request: PlatformTheme
The Theming is a great issue and #111 made me think.
Besides the technical issue, that flutter seems to have problems to automatically propagate down the cupertino theme, the point is, that iOS and android use different approached to styling and textTheming. Right now I use the MaterialTheme for fontsizes and styles. But it would actually make sense to use different styles on iOS and android, but I am to lazy and it feels not DRY enough to always use PlatformWidget for a headline or even make a own Widget for it.
A solution which comes to my mind would be to allow something like a PlatformTheme. I am not sure right now how that would look, but maybe someone else has a good idea.
Also this might even be a more flutter related issue, because they are unclear about theming, too. For example the ListTile subtitle is a blend of bodyText2, caption.color and in dense mode the hardcoded fontSize 12.0.
TextStyle _subtitleTextStyle(ThemeData theme, ListTileTheme tileTheme) {
final TextStyle style = theme.textTheme.bodyText2;
final Color color = _textColor(theme, tileTheme, theme.textTheme.caption.color);
return _isDenseLayout(tileTheme)
? style.copyWith(color: color, fontSize: 12.0)
: style.copyWith(color: color);
}
But still a developer has to cope with this on different platforms and this might be an appropriate case for PlatformTheme.
Theming between Material and Cupertino is quite different to eachother and having a PlatformTheme would need to cover a common interface between the two.
I did look into it a couple months ago but anything done could involve an opinionated design that I am trying to avoid as much as possible.
If you want however to attempt I do welcome PR's if they add value and can work cleanly on both material and ios platforms
I think having a PlatformTheme would be great too for the above mentioned reasons.
For now I'm using something like this:
typedef _CupertinoThemeBuilder<T> = T Function(CupertinoThemeData theme);
typedef _MaterialThemeBuilder<T> = T Function(ThemeData theme);
class PlatformTheme {
final BuildContext context;
PlatformTheme(this.context);
T call<T>({
@required _CupertinoThemeBuilder<T> cupertino,
@required _MaterialThemeBuilder<T> material,
}) {
if (isMaterial(context)) {
return material(Theme.of(context));
} else if (isCupertino(context)) {
return cupertino(CupertinoTheme.of(context));
}
return throw new UnsupportedError(
'This platform is not supported: $defaultTargetPlatform');
}
}
And using it like so:
Widget build(BuildContext context) {
final platformTheme = PlatformTheme(context);
return Text(
'Platform Widgets Are Cool',
platformTheme<TextStyle>(
cupertino: (theme) => theme.textTheme.navTitleTextStyle,
material: (theme) => theme.textTheme.headline4,
),
);
}
I think it looks cleaner than PlatformWidgets everywhere with two identical Text with platform specific styles.
Widget build(BuildContext context) {
return PlatformWidget(
cupertino: (context, __) {
return Text(
'Platform Widgets Are Cool',
style: Theme.of(context).textTheme.headline4,
);
},
material: (context, __) {
return Text(
'Platform Widgets Are Cool',
style: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle,
);
},
);
}
@pxsanghyo I have added something akin to what you posted.
@aqwert I like that approach as I am starting to use it. I set up to use Google Fonts package via setting up a Typographty class and than I just go through my PlatformText and set the style.
What I also like about the approach is that I can easily re-use that in a Root Widget when I do Goldens Testing... so I also get the styles applied during Goldens Testing.