I need to use theme extinction for colors for example inside theme extension for LargeBodyTextStyle
#immutable
class BodyLargeStyle extends ThemeExtension<BodyLargeStyle> {
final Color? color;
final double? fontSize;
final double? lineHeight;
final FontWeight? fontWeight;
final String? fontFamily;
const BodyLargeStyle({
required this.color,
required this.fontSize,
required this.lineHeight,
required this.fontWeight,
required this.fontFamily,
});
#override
ThemeExtension<BodyLargeStyle> copyWith() {
// TODO: implement copyWith
throw UnimplementedError();
}
#override
ThemeExtension<BodyLargeStyle> lerp(
ThemeExtension<BodyLargeStyle>? other, double t) {
// TODO: implement lerp
throw UnimplementedError();
}
static BodyLargeStyle bodyLargeStyle = BodyLargeStyle(
color: Theme.of(context).extension<CustomColors>()!.color,
fontSize: 12,
lineHeight: 1,
fontWeight: FontWeight.w400,
fontFamily: "any",
);
}
here I need to implement something like this but I don't have the context and I need to get use
of how theme Extention useful when changing from light to dark via verse
Related
Error is
The method 'Style.textStyle' has fewer positional arguments than those
of overridden method 'StyleHook.textStyle'. TextStyle textStyle(Color
color)
'Style.textStyle' ('TextStyle* Function(Color*)*') isn't a valid
override of 'StyleHook.textStyle' ('TextStyle Function(Color,
String?)').
Flutter Channel stable, 3.0.0
environment:
sdk: ">=2.7.2 <3.0.0"
Here is the problem #override TextStyle textStyle(Color color) { return TextStyle(color: color);
class Style extends StyleHook {
#override
double get activeIconSize => 28;
#override
double get activeIconMargin => 10;
#override
double get iconSize => 20;
#override
TextStyle textStyle(Color color) {
return TextStyle(color: color);
}
}
I had a similar problem using convex_bottom_bar.
The solution was posted at the following URL and I followed it and it solved the problem.
Error: The method 'Style.textStyle' has fewer positional arguments than
I looked at the StyleHook definition and found that a String type was optionally specified, so I changed it to accept it as shown below, and the error did not occur.
class Style extends StyleHook {
#override
double get activeIconSize => 30;
#override
double get activeIconMargin => 5;
#override
double get iconSize => 24;
#override
TextStyle textStyle(Color color, String s) {
return TextStyle(
fontSize: 11,
color: Colors.white,
);
}
}
I have proxy object companyCustomColors:
class CustomColors {
final CompanyCustomColors companyCustomColors;
CustomColors(BuildContext context)
: companyCustomColors =
Theme.of(context).extension<CompanyCustomColors>() ?? defaultColors;
Color get vipColor => companyCustomColors.vipColor;
Color get linksColor => companyCustomColors.linksColor;
Color get linkPressedColor => companyCustomColors.linkPressedColor;
}
Is it possible to use some Dart features (proxy, mixin, delegate) to get rid of these getters (vipColor, linksColor, linkPressedColor), but still have IDE autocomplete suggestions for CustomColors?
This object used like this one:
Text('sample',
style: TextStyle(
color: CustomColors(context).vipColor,
height: lineHeight,
),
)
Other classes used in this example:
class CompanyCustomColors extends ThemeExtension<CompanyCustomColors> {
const CompanyCustomColors({
required this.vipColor,
required this.linksColor,
required this.linkPressedColor,
});
final Color vipColor;
final Color linksColor;
final Color linkPressedColor;
}
const CompanyCustomColors defaultColors = CompanyCustomColors(
vipColor: AppColors.orange,
linksColor: AppColors.blue,
linkPressedColor: AppColors.blue_pressed,
);
I am using Firebase remote config to store my color values. This gives me the flexibilty to update colors without the need to update my app. Now I have written myself a helper function which returns the color object.
In my Firebase remote config I have stored the hex color codes as strings. However, now I am facing the problem that my colors are no constants (const). This is a huge problem for me as I have set default color values in some constructors like here:
const CustomIcon(
{required this.iconType,
this.size,
this.color = Helper.getColor("black"),
Key? key})
: super(key: key);
Because my color is not a const value anymore I get the following error: https://dart.dev/tools/diagnostic-messages#non_constant_default_value
This is my helper function:
static Color getColor(colorName) {
final remoteConfig = FirebaseRemoteConfig.instance;
String colorString = remoteConfig.getString(colorName);
const color = Color(int.parse(colorString));
return color;
}
Do you have any idea on how I can solve this problem?
Kind regards
You sadly won't be able to const anything from the API. The const keyword implies that the Dart Analyzer knows what the value will be even before compiling. This isn't the case here, as the values come from the API.
However, you can still have a solution, by using a local Color default value, and checking for a null color.
class CustomIcon extends StatelessWidget {
final String iconType;
final int? size;
final Color? color;
late final Color defaultColor = Helper.getColor("black");
CustomIcon({required this.iconType, this.size, this.color, Key? key})
: super(key: key);
#override
Widget build(BuildContext context) {
final _color = color ?? defaultColor;
// Build your Widget
return Container(
color: _color,
height: 50,
width: 50,
);
}
}
Here is a simple DartPad showing it in action: https://dartpad.dev/?id=562c943972abaefd29b7b264e16ad5aa
I came from a React world and trying to get my head around Flutter and Dart.
I'm using the Text widget with the same parameters a lot, so it seems reasonable to think of a way to reuse code. I created a wrapper that uses it:
import 'package:flutter/material.dart';
TextStyle getThemeProperty(type, TextTheme textTheme) {
switch (type) {
case 'headline1':
return textTheme.headline1;
case 'headline2':
return textTheme.headline2;
case 'headline3':
return textTheme.headline3;
default:
return textTheme.bodyText2;
}
}
class CustomText extends StatelessWidget {
const CustomText({Key key, this.type, this.text, this.color}) : super(key: key);
final type;
final text;
final color;
#override
Widget build(BuildContext context) {
var textTheme = Theme.of(context).textTheme;
var style = getThemeProperty(type, textTheme);
if (this.color != null) style.color = this.color;
return Text(
this.text,
style: style,
);
}
}
// Usage
CustomText(
text: 'Some Heading',
type: 'headline2',
color: Colors.black
)
The idea is to set the color if the color property is passed as a parameter, but Dart's compiler doesn't like it. It throws me the error: ''color' can't be used as a setter because it's final.
Try finding a different setter, or making 'color' non-final.'
I'm planning to do the same to fontWeight and textAlign properties as well. How am I able to make this work, I mean, to add new props to the style object on demand?
The reason why the dart compiler is unhappy is just because the color property of the TextStyle is declared as final. Therefore to use a new color, you have to create a new instance of the TextStyle.
Luckily, the TextStyle class comes with a copyWith method that returns an edited copy of your TextStyle
final type;
final text;
final color;
#override
Widget build(BuildContext context) {
var textTheme = Theme.of(context).textTheme;
var style = getThemeProperty(type, textTheme);
return Text(
this.text,
// Added this...
style: style.copyWith(color: color ?? style.color),
);
}
As a side note, when making reusable widgets, it's always a good idea to type your parameters. This is because any type of variable can be used. So instead of passing a String for text, you may pass an int
// DON'T DO THIS
final type;
final text;
final color;
// DO THIS
final String type;
final String text;
final Color color;
Also adding the this keyword to reference a variable in a class without variable shadowing is unnecessary.
// DON'T
this.text
// DO
text
I have created a CardText as a stateless widget and I will use it whenever I would be needing it. But I have a problem. As y'all can see, there are properties that I haven't marked as #required. What I want is these properties have a pre-defined value. Like, suppose the color property, it should be 0xFFFFFFFF until and unless I want somewhere to be as 0xFF000000. But these are final properties that can't be assigned on the basis of ??= method. Yes, I know, marking these properties as #required will require me to define each and every property whenever I call it. But having a pre-defined value will help me a lot to save time and a few lines of code.
Well, any expert out there, I don't know how to express the problem, so feel free to change the title. Thank you.
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class CardText extends StatelessWidget {
final String data;
final int color;
final int fontSize;
final FontWeight fontWeight;
const CardText(
this.data, {
this.color,
this.fontSize,
this.fontWeight,
});
#override
Widget build(BuildContext context) {
return Text(
data,
style: GoogleFonts.openSans(
textStyle: TextStyle(
fontSize: fontSize,
fontWeight: fontWeight,
color: Color(color),
),
),
);
}
}
If your arguments are optional then you can give default it right away, like following
const CardText({
this.data,
this.color = 0xFFFFFFFF,
this.fontSize = 14,
this.fontWeight,
})
You can use the : colon syntax:
const CardText(
this.data, {
this.color,
this.fontSize,
this.fontWeight,
}) : color = 0xFFFFFFFF, data = "data"
The code after the colon will be executed before the code inside the curly brackets. From the linked question
The part after : is called "initializer list. It is a ,-separated list
of expressions that can access constructor parameters and can assign
to instance fields, even final instance fields. This is handy to
initialize final fields with calculated values.