Flutter back button is hidden on navigation - flutter

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(),
);
}

Related

is it possible to use if statements to change the font size in themedata based off the size of the screen (media query)?

I'm trying to set the font size of the text in my app through the themeData using media Query.
eg. if screen size is smaller the x, font size should be x.
is this even possible to achieve? and if so, how would I go about it?
here is my MyApp code in my main.dart:
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: Colors.black,
textTheme: TextTheme(
bodyText1: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'SourceSansPro',
),
),
),
debugShowCheckedModeBanner: false,
initialRoute: '/second',
routes: {
'/': (context) => pageone(),
'/first': (context) => pagetwo(),
'/second': (context) => pagethree(),
});
}
}
When I try and use var screenSize = MediaQuery.of(context).size; as a variable into MyApp, i'm getting an error on context.
thanks so much and any help would be greatly appreciated.
I would create multiple TextThemes, one for each screen size you want to support:
TextTheme smallTextTheme = TextTheme(
bodySmall: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'SourceSansPro',
fontSize: 14,
),
bodyMedium: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'SourceSansPro',
fontSize: 16,
),
);
TextTheme largeTextTheme = TextTheme(
bodySmall: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'SourceSansPro',
fontSize: 18,
),
bodyMedium: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'SourceSansPro',
fontSize: 20,
),
);
Then in MaterialApp, you can determine which TextTheme you use based on the screen size:
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: WidgetsBinding.instance.window.physicalSize.width > 600 ? largeTextTheme : smallTextTheme,
),
home: const MyHomePage(),
);
See this answer for how to use the device size in the MaterialApp widget. If you try to use MediaQuery, you will get an error like this:
No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of(). This can happen because you have not added a WidgetsApp, CupertinoApp, or MaterialApp widget (those widgets introduce a MediaQuery), or it can happen if the context you use comes from a widget above those widgets.
You need to separate the context(initialize on top level). then you will be able to read.
You can do
void main() {
runApp(const MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
return Theme(
data: ThemeData.dark().copyWith(
scaffoldBackgroundColor: Colors.black,
textTheme: TextTheme(
bodyText1: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'SourceSansPro',
),
),
),
child: Scaffold(),
);
}
}
But I think it is not necessary to increase the font size.

How to change the textTheme in the ThemeData class?

I cannot change the color of the TextTheme property in the ThemeData class even though the code doesn't give any error.
Here is what I have done so far:
import 'package:flutter/material.dart';
void main() => runApp(BMICalculator());
class BMICalculator extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
appBarTheme: AppBarTheme(
backgroundColor: Color(0xff0a0e21),
),
scaffoldBackgroundColor: Color(0xff0a0e21),
textTheme: TextTheme(bodyText1: TextStyle(color: Colors.blue)),//the text remains white in the app.
),
home: InputPage(),
);
}
}
class InputPage extends StatefulWidget {
#override
_InputPageState createState() => _InputPageState();
}
class _InputPageState extends State<InputPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BMI CALCULATOR'),
),
body: Center(
child: Text('Body Text'),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => print('object'),
),
);
}
}
What am I doing wrong?
You have declared the themes successfully, but are not using it. Here is the replacement code snippet:
body: Center(
child: Text('Body Text', style: Theme.of(context).textTheme.bodyText1),
)
You need to specify the theme in style attribute for the necessary changes to take place.
Try passing textTheme: ThemeData value
here is an example for textTheme
textTheme: ThemeData.light().textTheme.copyWith(
headline6: TextStyle(
fontFamily: 'OpenSans',
fontSize: 18,
fontWeight: FontWeight.bold,
),
Just match your implementation with mine, here I have implemented textTheme for titles.
now if I want to refer to this headline6 theme I can do
Theme.of(context).textTheme.headline6
As much as I know there are a-lot of different properties in TextTheme class, such as bodytext1, bodytext2, headline1, headline2, caption etc etc...
And you can configure many of them to use them later, but there is no catalog or confirmation that which part of the app it will be applied to, i.e. Out of all the places that uses the text widget, to which bodytext1 will be applied to it is not known...but overtime you will get the feel for it.
But for now you have to call it manually where-ever you want to use that specific text configuration, such as in your code you have to do it like:
return Scaffold(
appBar: AppBar(
title: Text('BMI CALCULATOR'),
),
body: Center(
child: Text('Body Text', style: Theme.of(context).textTheme.bodyText1,),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => print('object'),
),
);
The main point of adding theme is code-reusability and making it dynamic which is obviously achieved by this too.

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.

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.

Use of DefaultTextStyle in 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