Reputation: 3849
I'm attempting to pass color/theme information different widgets. My app consists of a news page which then opens up individual articles. These articles should have different colors depending on which of several news pages opens them, so I want to direct the theme/color information from outside my article widget.
I made a class to hold some color/theme information as follows:
class NewsTheme0 {
static Color headerColor = Color.fromRGBO(30, 60, 90, 1);
static TextStyle headerFontStyle() {
return TextStyle(
color:Color.fromRGBO(200,100,0,1),
fontSize:28.5,
letterSpacing: -1.4,
fontWeight: FontWeight.w700
);
}
}
class NewsTheme1 {
static Color headerColor = Color.fromRGBO(0, 0, 0, 1);
static TextStyle headerFontStyle() {
return TextStyle(
color:Color.fromRGBO(255, 255, 255, 1),
fontSize:15,
fontWeight: FontWeight.w700
);
}
}
And then inside my News
page in my appBar
I'm successfully retrieving this color information:
Scaffold(
appBar: AppBar(
centerTitle: false,
backgroundColor: NewsTheme0.headerColor,
title: Text('News',
style: NewsTheme0.headerFontStyle()),
elevation: 0,
) ...
From my main News
page I open an Article
page and when I open the article widget, I pass the color information
Navigator.push(
context,
MaterialPageRoute(builder: (context) => OpenAnArticle(articleid: 231, theme: NewsTheme0)));
And inside my article looks like this:
class OpenAnArticle extends StatefulWidget {
OpenAnArticle({ Key? key, required this.articleid, required this.theme}) : super(key: key);
final int articleid;
final theme;
@override
_OpenAnArticle createState() => _OpenAnArticle();
}
BUT when I try to use this theme information in my article
, it fails miserably. I need to pass the theme information because I will not know ahead of time from which of my various color theme pages they will be arriving from.
Scaffold(
appBar: AppBar(
centerTitle: false,
backgroundColor: widget.theme.headerColor,
title: Text('Article',
style: widget.theme.headerFontStyle()),
elevation: 0,
) ...
Upvotes: 1
Views: 585
Reputation: 11486
That's because when you do NewsTheme0
, you're accessing an object of type Type
and you can't access the (static) methods of a class using only its type. You can use a "enum" as seen here:
// Declaring the abstract class which each theme will inherit from
abstract class NewsTheme {
static const NewsTheme theme0 = _NewsTheme0();
static const NewsTheme theme1 = _NewsTheme1();
const NewsTheme();
Color get headerColor;
TextStyle headerFontStyle();
}
class _NewsTheme0 extends NewsTheme {
const _NewsTheme0() : super();
@override
Color get headerColor => Color.fromRGBO(30, 60, 90, 1);
@override
TextStyle headerFontStyle() {
return TextStyle(
color:Color.fromRGBO(200,100,0,1),
fontSize:28.5,
letterSpacing: -1.4,
fontWeight: FontWeight.w700
);
}
}
class _NewsTheme1 extends NewsTheme {
const _NewsTheme1() : super();
@override
Color get headerColor => Color.fromRGBO(0, 0, 0, 1);
@override
TextStyle headerFontStyle() {
return TextStyle(
color:Color.fromRGBO(255, 255, 255, 1),
fontSize:15,
fontWeight: FontWeight.w700
);
}
}
In your widget's code:
class OpenAnArticle extends StatefulWidget {
final int articleid;
// Expect a NewsTheme object
final NewsTheme theme;
const OpenAnArticle({ Key? key, required this.articleid, required this.theme}) : super(key: key);
@override
_OpenAnArticle createState() => _OpenAnArticle();
}
Then, if you want to pass a theme to its constructor, you can just access the static fields of NewsTheme
:
Navigator.push(
context,
MaterialPageRoute(builder: (_) => OpenAnArticle(articleid: 231, theme: NewsTheme.theme0)),
);
Upvotes: 3