How do I adjust the margin for Flutter AppBar? - flutter

How do I customize the app bar such that the back button is not so close to the border? I want to achieve this for all pages.
I can't seem to set margins for the app bar.
Reference to the back button close to border
Here are my codes
// General Theme
AppBarTheme(
centerTitle: true,
iconTheme: IconThemeData(color: Colors.black),
backgroundColor: Colors.transparent,
elevation: 0,
textTheme: TextTheme(
headline6: TextStyle(
color: kTextColor,
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
);
// Individual Screen
import 'package:flutter/material.dart';
import 'components/body.dart';
class SplashScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hello'),
),
body: Body(),
);
}
}

You may have to create your own custom widget for this, your custom widget can be a Row widget with multiples child.
Also, checkout SafeArea widget.
class SplashScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: MyCustomWidget(title: 'Hello'),
),
body: Body(),
);
}
}

Related

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.

make appbar the same color of the body

I need to use the property of AppBar, but I need the app bar to be the same color as the body. As if there is no appbar. I used the same color to the body and appBar but the appBar have a darker color!
Material App code:
class MyApp extends StatelessWidget {
const MyApp();
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'AppName',
theme: ThemeData(
backgroundColor: Color(pagesBackgroundColor),
appBarTheme: AppBarTheme(
color: Color(pagesBackgroundColor),
),
),
home: const HomePage(),
);
}
}
Home Page Code:
class HomePage extends StatelessWidget {
const HomePage();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color(pagesBackgroundColor),
title: Text(
"What's up!",
style: TextStyle(color: Colors.black),
),
elevation: 0.0,
),
body: Column(),
);
}
}
set appbar color to transparent:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
title: Text(
"What's up!",
style: TextStyle(color: Colors.black),
),
elevation: 0.0,
),
body: Column(),
);
I suggest removing the appBar completely and use the Align widget to place your other widget on top of the page like it was the appBar.
If you do remove the appBar, make sure to place your Scaffold inside a SafeArea widget.
I hope this helps until someone else can show how to make the appBar background color invisible.
return SafeArea(
child: Scaffold(
body: ListView(
children: [
Align(
alignment: Alignment.topLeft,
child: TextButton(),
)
],
),
),
);

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.

How to change the appBar back button color

I cannot figure out how to change the appBar's automatic back button to a different color. it's under a scaffold and I've tried to research it but I can't wrap my head around it.
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: Image.asset(
'images/.jpg',
fit: BoxFit.fill,
),
centerTitle: true,
),
You have to use the iconTheme property from the AppBar , like this:
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
title: Text("Sample"),
centerTitle: true,
),
Or if you want to handle the back button by yourself.
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
title: Text("Sample"),
centerTitle: true,
),
Even better, only if you want to change the color of the back button.
appBar: AppBar(
leading: BackButton(
color: Colors.black
),
title: Text("Sample"),
centerTitle: true,
),
you can also override the default back arrow with a widget of your choice, via 'leading':
leading: new IconButton(
icon: new Icon(Icons.arrow_back, color: Colors.orange),
onPressed: () => Navigator.of(context).pop(),
),
all the AppBar widget does is provide a default 'leading' widget if it's not set.
It seemed to be easier to just create a new button and add color to it, heres how i did it for anyone wondering
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: BackButton(
color: Colors.black
),
You can also set leading icon color globally for the app
MaterialApp(
theme: ThemeData(
appBarTheme: AppBarTheme(
iconTheme: IconThemeData(
color: Colors.green
)
)
)
)
Set back button color globally
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
appBarTheme: AppBarTheme(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.black), // set backbutton color here which will reflect in all screens.
),
),
home: LoginScreen(),
);
Also,
To change SliverAppBar
SliverAppBar(
iconTheme: IconThemeData(
color: Colors.white, //change your color here
),
AppBar(
automaticallyImplyLeading: false,
leading: Navigator.canPop(context)
? IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.black,
size: 47,
),
onPressed: () => Navigator.of(context).pop(),
)
: null,
);
To customise the leading icon, you may want to mimic the functionality of the AppBar widget, which properly handles showing a back button, drawer icon, or close icon, depending on the current context. Here is an example which replaces the default icons.
import 'package:flutter/material.dart';
class TopBar extends StatelessWidget with PreferredSizeWidget {
static const double _topBarHeight = 60;
#override
Widget build(BuildContext context) {
return AppBar(
toolbarHeight: _topBarHeight,
title: Text('Title'),
automaticallyImplyLeading: false,
leading: _buildLeadingWidget(context),
);
}
#override
Size get preferredSize => Size.fromHeight(_topBarHeight);
Widget _buildLeadingWidget(BuildContext context) {
final ScaffoldState scaffold = Scaffold.of(context);
final ModalRoute<dynamic> parentRoute = ModalRoute.of(context);
final bool canPop = ModalRoute.of(context)?.canPop ?? false;
final bool hasDrawer = scaffold?.hasDrawer ?? false;
final bool useCloseButton = parentRoute is PageRoute<dynamic> && parentRoute.fullscreenDialog;
Widget leading;
if (hasDrawer) {
leading = IconButton(
icon: const Icon(Icons.menu_rounded),
onPressed: Scaffold.of(context).openDrawer,
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
);
} else {
if (canPop) {
if (useCloseButton) {
leading = IconButton(
color: Theme.of(context).colorScheme.onBackground,
icon: Icon(Icons.close_rounded),
onPressed: () => Navigator.of(context).maybePop());
} else {
leading = IconButton(
padding: EdgeInsets.all(0),
iconSize: 38,
icon: Icon(Icons.chevron_left_rounded),
onPressed: Navigator.of(context).pop);
}
}
}
return leading;
}
}
This class uses the PreferredSizeWidget as a mixin, so you can use it as a replacement for an existing AppBar widget in a Scaffold. Note the _buildLeadingWidget method, which only shows a back button if necessary, and shows a menu button if a drawer is present, or a close button if a full-screen dialog is displayed.
You can use foregroundColor property. For example:
AppBar(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
title: const Text('Black title and back icon on a white AppBar'),
)
To change the leading color for CupertinoPageScaffold
Theme(
data: Theme.of(context).copyWith(
cupertinoOverrideTheme: CupertinoThemeData(
scaffoldBackgroundColor: Colors.white70,
primaryColor: Styles.green21D877, // HERE COLOR OF LEADING
),
),
child: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
brightness: Brightness.light,
backgroundColor: Colors.white,
middle: Text('Cupertino App Bar'),
),
child: Container(
child: Center(
child: CupertinoActivityIndicator(),
),
),
),
)
You can use iconTheme like the following code:
iconTheme: IconThemeData(
color: Colors.black, // <= You can change your color here.
),
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.white, //modify arrow color from here..
),
);
In the AppBar, add the leading parameter and assign the BackButton widget. Then add the color parameter to the BackButton as below:
AppBar(
leading: const BackButton(
color: Colors.black, // Change the color here
),
centerTitle: true,
)
You can customize the AppBarWidget, keyword with is important, or you can assign your custom AppBarWidget to appBar property of Scaffold:
import 'package:flutter/material.dart';
double _getAppBarTitleWidth(
double screenWidth, double leadingWidth, double tailWidth) {
return (screenWidth - leadingWidth - tailWidth);
}
class AppBarWidget extends StatelessWidget with PreferredSizeWidget {
AppBarWidget(
{Key key,
#required this.leadingChildren,
#required this.tailChildren,
#required this.title,
this.leadingWidth: 110,
this.tailWidth: 30})
: super(key: key);
final List<Widget> leadingChildren;
final List<Widget> tailChildren;
final String title;
final double leadingWidth;
final double tailWidth;
#override
Widget build(BuildContext context) {
// Get screen size
double _screenWidth = MediaQuery.of(context).size.width;
// Get title size
double _titleWidth =
_getAppBarTitleWidth(_screenWidth, leadingWidth, tailWidth);
double _offsetToRight = leadingWidth - tailWidth;
return AppBar(
title: Row(
children: [
Container(
width: leadingWidth,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: leadingChildren,
),
),
Container(
color: Colors.green,
width: _titleWidth,
padding: const EdgeInsets.only(left: 5.0, right: 5),
child: Container(
padding: EdgeInsets.only(right: _offsetToRight),
color: Colors.deepPurpleAccent,
child: Center(
child: Text('$title'),
),
),
),
Container(
color: Colors.amber,
width: tailWidth,
child: Row(
children: tailChildren,
),
)
],
),
titleSpacing: 0.0,
);
}
#override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
The following is the example about how to use it:
import 'package:flutter/material.dart';
import 'package:seal_note/ui/Detail/DetailWidget.dart';
import 'package:seal_note/ui/ItemListWidget.dart';
import 'Common/AppBarWidget.dart';
import 'Detail/DetailPage.dart';
class MasterDetailPage extends StatefulWidget {
#override
State<StatefulWidget> createState() => _MasterDetailPageState();
}
class _MasterDetailPageState extends State<MasterDetailPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarWidget(leadingChildren: [
IconButton(
icon: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
),
Text(
'文件夹',
style: TextStyle(fontSize: 14.0),
),
], tailChildren: [
Icon(Icons.book),
Icon(Icons.hd),
], title: '英语知识',leadingWidth: 140,tailWidth: 50,),
body: Text('I am body'),
);
}
}