Use of DefaultTextStyle in flutter - flutter

I am trying to apply a DefaultTextStyle, but even though the style is defined and available (as established by calling DefaultTextStyle.of(context).style), it does not get applied by default to child Text objects. So what am I doing wrong, or failing to understand?
Here is the build method from my calling class, where I define my DefaultTextStyle:
Widget build(BuildContext context) {
return new MaterialApp(
onGenerateTitle: (BuildContext context) =>
Strings.of(context).getStr('app_title'),
localizationsDelegates: [
const StringsDelegate(),
GlobalWidgetsLocalizations.delegate,
],
localeResolutionCallback: Strings.resolveLocale,
// Watch out: MaterialApp creates a Localizations widget
// with the specified delegates. DemoLocalizations.of()
// will only find the app's Localizations widget if its
// context is a child of the app.
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new DefaultTextStyle(
style: new TextStyle(
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
decorationColor: Colors.red,
decorationStyle: TextDecorationStyle.wavy,
color: Colors.blue
),
child: new StatusPage())
);
}
And here is StatusPage, where I am trying to use the DefaultTextStyle:
class StatusPage extends MyStatelessWidget {
#override
Widget build(BuildContext context) {
TextStyle style = DefaultTextStyle.of(context).style;
print("STYLE: $style");
return new Scaffold(
appBar: new AppBar(
title: getText(context, 'app_title')
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text('wibble', style:style),
new ActivityStatus(),
new MonitoringStatus()]
)));
}
}
With the code as shown, the Text "wibble" is correctly shown with the appropriate style. My understanding from the docs, is that this style should be applied by default, so I should not need the style argument to the Text constructor for "wibble".
However, if I remove the style argument I do not get the style from my DefaultTextStyle.
What am I missing?

Apply the DefaultTextStyle to the Scaffold like this and you will get this style in all the descendant Text widgets
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new StatusPage());
}
}
class StatusPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
TextStyle style = DefaultTextStyle.of(context).style;
return new Scaffold(
appBar: new AppBar(),
body: new DefaultTextStyle(
style: new TextStyle(
inherit: true,
fontSize: 20.0,
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
decorationColor: Colors.red,
decorationStyle: TextDecorationStyle.wavy,
color: Colors.blue),
child: new Center(
child: new Column(
children: <Widget>[
new Text("hello"),
],
),
)));
}
}

I had same issue before, I think it comes when using custome fonts or changing language (at least that was my case)
the solution for me was to go MaterialApp widget and then override ALL textTheme attributes like this:
fontFamily: "STCBold",
textTheme: GoogleFonts.cairoTextTheme(textTheme).copyWith(
headline1: TextStyle(height: 1),
headline2: TextStyle(height: 1),
headline3: TextStyle(height: 1),
headline4: TextStyle(height: 1),
headline5: TextStyle(height: 1),
headline6: TextStyle(height: 1),
subtitle1: TextStyle(height: 1),
subtitle2: TextStyle(height: 1),
bodyText1: TextStyle(height: 1),
bodyText2: TextStyle(height: 1),
caption: TextStyle(height: 1),
button: TextStyle(height: 1),
overline: TextStyle(height: 1),
),
this will make all text themes have no extra padding thus all texts will be tight. but make sure to use style: Theme.of(context).textTheme.WHATEVERTEXT. in all your code

Related

How to set input text color when defining a theme?

I define my theme as follows:
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: bgColor,
textTheme: GoogleFonts.poppinsTextTheme(Theme.of(context).textTheme)
.apply(bodyColor: Colors.white),
canvasColor: secondaryColor,
),
How can I also change the color of text in TextFields? Do I have to modify the copyWith() call somehow?
Edit: I think I have a special case, because I'm using Flutter Login, I'm not sure if that changes things.
TextFields use subtitle1 text style by default, so the first way to change text color is to set subtitle1's style:
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
subtitle1: TextStyle(color: Colors.pink),
),
),
home: HomePage(),
);
}
}
You can also specify style overrides directly from TextField's style parameter:
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
Row(
children: [
Expanded(
child: TextField(
style: TextStyle(color: Colors.orange),
),
),
],
),
],
),
);
}
}
I tried Your code and it works fine for me:
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: Colors.grey[900],
textTheme: GoogleFonts.poppinsTextTheme()
.apply(bodyColor: Colors.white)
.copyWith(subtitle1: TextStyle(color: Colors.purple)),
canvasColor: Colors.grey[800],
),
home: HomePage(),
);
}
In terms of performance, copyWith is a lot lighter than apply because it doesn't have to recreate all styles.

Getting Error in flutter MediaQuery.of() called with a context that does not contain a MediaQuery

I didn't understand what the error is. I am returning a Scaffold widget. There are no syntax errors detected by visual studio code. I am getting an error while running the app.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("here is my text")),
body: Text(
'No, we need bold strokes. We need this plan.',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue.withOpacity(0.7),
height: 1,
fontSize: 20,
decoration: TextDecoration.underline,
decorationColor: Colors.green,
decorationStyle: TextDecorationStyle.wavy,
backgroundColor: Colors.red),
),
);
}
}
If I wrap the scaffold widget in the material app it is working. Can anyone explain to me the reason?
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("here is my text")),
body: Text(
'No, we need bold strokes. We need this plan.',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue.withOpacity(0.7),
height: 1,
fontSize: 20,
decoration: TextDecoration.underline,
decorationColor: Colors.green,
decorationStyle: TextDecorationStyle.wavy,
backgroundColor: Colors.red),
),
),
);
}
}
The top most widget must be wrapped in a MaterialApp widget. This is what generates the context chain that it's looking for.
Media Query is a property of MaterialApp so if you don't use the MaterialApp, you can't access media query. The proper way is to use it in your main class.

error when I use ScreenUtil library in flutter

I am trying to use ScreenUtil() to make my text font size responsive.
This line caused an error "ScreenUtil.init(context);".
And the error is "MediaQuery.of() called with a context that does not contain a MediaQuery."
Widget build(BuildContext context) {
ScreenUtil.init(context);
return MaterialApp(
title: 'Meals App',
theme: ThemeData(
primarySwatch: Colors.pink,
accentColor: Colors.amber,
canvasColor: Color.fromRGBO(255, 254, 229, 1),
fontFamily: 'Raleway',
textTheme: TextTheme(
headline6: TextStyle(
fontSize: ScreenUtil().setSp(100),
fontFamily: 'RobotoCondensed',
fontWeight: FontWeight.bold,
),
bodyText1: TextStyle(color: Color.fromRGBO(20, 51, 51, 1)),
bodyText2: TextStyle(color: Color.fromRGBO(20, 51, 51, 1)),
),
),
home: TabsScreen(favouriteMeals),
);
}
You can copy paste run full code below
You can use builder of MaterialApp
code snippet
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter_ScreenUtil',
builder: (context, widget) {
ScreenUtil.init(context,
width: 750, height: 1334, allowFontScaling: false);
return widget;
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
working demo
full code
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
void main() => runApp(MyApp());
class TextStyles {
TextStyle t1 = TextStyle(fontSize: 24.ssp, color: Colors.black);
TextStyle t2 = TextStyle(fontSize: 24.sp, color: Colors.black);
}
var ts = TextStyles();
class TextStyle2 {
static TextStyle2 ts2;
factory TextStyle2() {
if (ts2 == null) {
ts2 = TextStyle2();
}
return ts2;
}
TextStyle t1 = TextStyle(fontSize: 24.ssp, color: Colors.black);
TextStyle t2 = TextStyle(fontSize: 24.sp, color: Colors.black);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter_ScreenUtil',
builder: (context, widget) {
ScreenUtil.init(context,
width: 750, height: 1334, allowFontScaling: false);
return widget;
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
//Set the fit size (fill in the screen size of the device in the design) If the design is based on the size of the iPhone6 ​​(iPhone6 ​​750*1334)
//ScreenUtil.init(context, width: 750, height: 1334, allowFontScaling: false);
return ExampleWidget(title: 'FlutterScreenUtil Demo');
}
}
class ExampleWidget extends StatefulWidget {
const ExampleWidget({Key key, this.title}) : super(key: key);
final String title;
#override
_ExampleWidgetState createState() => _ExampleWidgetState();
}
class _ExampleWidgetState extends State<ExampleWidget> {
#override
Widget build(BuildContext context) {
printScreenInformation();
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
width: 375.w,
height: 200.h,
color: Colors.red,
child: Text(
'My width:${375.w}dp \n'
'My height:${200.h}dp',
style: TextStyle(
color: Colors.white, fontSize: ScreenUtil().setSp(24)),
),
),
Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
width: ScreenUtil().setWidth(375),
height: ScreenUtil().setHeight(200),
color: Colors.blue,
child: Text(
'My width:${0.5.wp}dp \n'
'My height:${ScreenUtil().setHeight(200)}dp',
style: TextStyle(
color: Colors.white,
fontSize: ScreenUtil().setSp(24))),
),
],
),
Text('Device width:${ScreenUtil.screenWidthPx}px'),
Text('Device height:${ScreenUtil.screenHeightPx}px'),
Text('Device width:${ScreenUtil.screenWidth}dp'),
Text('Device height:${ScreenUtil.screenHeight}dp'),
Text('Device pixel density:${ScreenUtil.pixelRatio}'),
Text('Bottom safe zone distance:${ScreenUtil.bottomBarHeight}dp'),
Text('Status bar height:${ScreenUtil.statusBarHeight}dp'),
Text(
'Ratio of actual width dp to design draft px:${ScreenUtil().scaleWidth}',
textAlign: TextAlign.center,
),
Text(
'Ratio of actual height dp to design draft px:${ScreenUtil().scaleHeight}',
textAlign: TextAlign.center,
),
SizedBox(
height: ScreenUtil().setHeight(100),
),
Text('System font scaling factor:${ScreenUtil.textScaleFactor}'),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'My font size is 24px on the design draft and will not change with the system.',
style: TextStyle(
color: Colors.black,
fontSize: 24.sp,
)),
Text(
'My font size is 24px on the design draft and will change with the system.',
style: ts.t1),
],
)
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.title),
onPressed: () {
ScreenUtil.init(context,
width: 1500, height: 1334, allowFontScaling: false);
setState(() {});
},
),
);
}
void printScreenInformation() {
print('Device width dp:${ScreenUtil.screenWidth}'); //Device width
print('Device height dp:${ScreenUtil.screenHeight}'); //Device height
print(
'Device pixel density:${ScreenUtil.pixelRatio}'); //Device pixel density
print(
'Bottom safe zone distance dp:${ScreenUtil.bottomBarHeight}'); //Bottom safe zone distance,suitable for buttons with full screen
print(
'Status bar height px:${ScreenUtil.statusBarHeight}dp'); //Status bar height , Notch will be higher Unit px
print(
'Ratio of actual width dp to design draft px:${ScreenUtil().scaleWidth}');
print(
'Ratio of actual height dp to design draft px:${ScreenUtil().scaleHeight}');
print(
'The ratio of font and width to the size of the design:${ScreenUtil().scaleWidth * ScreenUtil.pixelRatio}');
print(
'The ratio of height width to the size of the design:${ScreenUtil().scaleHeight * ScreenUtil.pixelRatio}');
print('System font scaling:${ScreenUtil.textScaleFactor}');
print('0.5 times the screen width:${0.5.wp}');
print('0.5 times the screen height:${0.5.hp}');
}
}
Please try this.
Widget build(BuildContext context) {
return Builder(builder:(ctx){
ScreenUtil.init(ctx);
return MaterialApp(
title: 'Meals App',
theme: ThemeData(
primarySwatch: Colors.pink,
accentColor: Colors.amber,
canvasColor: Color.fromRGBO(255, 254, 229, 1),
fontFamily: 'Raleway',
textTheme: TextTheme(
headline6: TextStyle(
fontSize: ScreenUtil().setSp(100),
fontFamily: 'RobotoCondensed',
fontWeight: FontWeight.bold,
),
bodyText1: TextStyle(color: Color.fromRGBO(20, 51, 51, 1)),
bodyText2: TextStyle(color: Color.fromRGBO(20, 51, 51, 1)),
),
),
home: TabsScreen(favouriteMeals),
);});
}
This will introduce a new context with a new MediaQuery
if you just want to migrate slowly screens one by one or just for specific widget you can try this.
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
ScreenUtil.init(
constraints,
allowFontScaling: false,
designSize: Size(1080, 300),
);
return Scaffold(
backgroundColor: Color(0xFFFCBDE9),
resizeToAvoidBottomInset: false,
body: Column(
children: [
_buildAppBar(context),
],
),
);
},
);
}
You are welcome to use the screenutil plug-in, see that there is a problem with your usage
ScreenUtil.init should be used in the subcomponents of MaterialApp。
like this:
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Module',
builder: FlutterBoost.init(postPush: _onRoutePushed),
home: EmptyPage());
}
·······
class EmptyPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
ScreenUtil.init(context, width: 320, height: 568, allowFontScaling: false);
return Scaffold(
body: Container(),
);
}
}
If you want to use it outside , you can use v4.
https://pub.flutter-io.cn/packages/flutter_screenutil/versions/4.0.0-beta2
Please read the document carefully

Flutter back button is hidden on navigation

Why MaterialApp hides back button from AppBar for my new screen. I have many screens in my app, where I need to use ThemeData. To do that, I use MaterialApp in another screen, but I don't see any back arrow on the AppBar().
return MaterialApp(
theme: ThemeData(
fontFamily: 'IranSansLight',
textTheme: TextTheme(
headline: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold, fontFamily: 'IranSansLight'),
title: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic, fontFamily: 'IranSansLight'),
body1: Theme.of(context).textTheme.caption.copyWith(fontFamily: 'IranSansLight', color: Colors.black)),
),
home: ScopedModel(
model: CounterModel(),
child: Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
appBar: AppBar(automaticallyImplyLeading:true,title: Text('aaaa'),),
body: Container(
)),
),
),
);
}
You are using MaterialApp for all individual screens, this is not the correct way, all you need is just one MaterialApp for the entire app.
void main() {
runApp(
MaterialApp(home: HomePage()), // MaterialApp widget should be used only here
);
}
And whenever you need to use Theme in your 2nd screen, use something like:
#override
Widget build(BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(
// override whatever you need like
textTheme: TextTheme(...),
),
child: Scaffold(),
);
}

Flutter Text Color Theme doesn't work under ListTile title

I am getting started in Flutter and just trying out stuff.
I set a custom theme, but Text Widgets under the title property of ListTile don't get the right color. Also Icons under the leading property don't get the right color as well.
I tried setting some other colors, and sorted out, that the Problem only exists within that element.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp',
theme: ThemeData(
primaryColor: Colors.black,
scaffoldBackgroundColor: Color(0xff202020),
cardTheme: CardTheme(color: Colors.black),
textTheme: TextTheme(
body1: TextStyle(color: Colors.white),
subtitle: TextStyle(color: Colors.white),
headline: TextStyle(color: Colors.white)),
iconTheme: IconThemeData(color: Colors.white)),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("HomePage"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
tooltip: "back to the last page.",
onPressed: () {
Navigator.pop(context);
})
),
body: Card(
child: ListTile(
title: Text("Test"),
leading: new Icon(Icons.devices)
),
));
}
}
The Text for the title should appear white as well as the icon, instead it is black. All other Text is white.
The title on ListTile is using subhead textStyle of Theme. So if you want config color of ListTile on ThemeData you need change subhead.
textTheme: TextTheme(
subhead: TextStyle(color: Colors.white),
...)
In order to make use of you're theme you need to use Theme.of(context).
Container(
color: Theme.of(context).accentColor,
child: Text(
'Text with a background color',
style: Theme.of(context).textTheme.title,
),
);
Read more about it here in the cookbook. You are on the right track
https://flutter.dev/docs/cookbook/design/themes
In Flutter 3 which I'm currently using, titleMedium defines the text style for title of ListTiles.
MaterialApp(
theme: ThemeData(
textTheme: Typography().black.copyWith(
titleMedium: const TextStyle(
fontSize: 32,
),
),
)
For example the above theme makes theme relatively large.
Flutter team should provide developers with a reference for these styles. For the moment you can find out which style corresponds to which widget by trial and error.
Just change body1 to bodyText1 in the following location:
C:\src\flutter.pub-cache\hosted\pub.dartlang.org\charts_flutter-0.9.0\lib\src\behaviors\legend\legend_entry_layout
This will solve the issue.