How to change default back button icon in Flutter? - flutter

How I will change the back button icon in flutter using the theme. So it can be reflected throughout the application. I saw multiple options in the theme to change the size and color of the icon. But didn't see the change icon option.

Example:
Scaffold(
appBar(
leading: BackButton(), // icon depends on TargetPlattrom
),
),
Or you can create your own constant widget basis on IconButton with your own icon settings, than use it as value for leading property. In addition, there is an AppBarTheme class, which can be used when you create instance of ThemeData.
https://api.flutter.dev/flutter/material/AppBarTheme-class.html
P.S. If you look at AppBar source code you see that regular widget CloseButton or BackButton are used. So there is no specific style for it. And you have 2 ways:
Create your own global widget and use it in each Scaffold.
Subclass Scaffold with your own leading property and use it.

appBar: AppBar(
automaticallyImplyLeading: false,
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: const Icon(Icons.alarm_on), // Put icon of your preference.
onPressed: () {
// your method (function),
},
);
},
),
title: Text(widget.title),
centerTitle: true,
The above code will change the default back icon to alarm on icon. You can change it to any thing.

I'm not sure if this is the right way to do this. I'm still learning and I don't know if this will work in all cases. I've done this using VS Code while my app is in development.
I looked up the backbutton references(Shift + Alt + F12) and found the actual button in flutter sdk. I changed it there in the back_button.dart file which can be found in your flutter installation folder : c:\flutter\packages\flutter\lib\src\material\back_button.dart
There, edit the static IconData method of the button and choose any Icon you wanna use for any platform.
static IconData _getIconData(TargetPlatform platform) {
switch (platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return Icons.arrow_back_ios;
}
}
In the above case Icons.arrow_back_ios will be returned in all platforms. You can specify the return Icon for each platform.
However, I haven't tested this in like a real world "production use" situation so I hope someone else here can clarify.

This will do the job for you:
IconButton(
onPressed: (){
Navigator.pop(context);
},
icon:Icon(Icons.arrow_back_ios),
//replace with our own icon data.
)
For the future seekers like me.

Related

flutter constant appbar on different screen navigation

I am developing an app in flutter with few screen I want to add AppBar in home screen and want that appbar to be fixed in all screen, but in the dummy code which i have written the complete screen is getting replaced by that.
Below is the screen
HomeScreen - here i have created appbar
When I click on AddPolicy Button, i get that screen where right now i just have a text but the complete screen gets replaced as below, but I want the header appBar should be fixed. How can I achieve this.
Below is the code
homepage - https://github.com/lodha13/samkit/blob/main/lib/screens/home.dart
AddPolicy page - https://github.com/lodha13/samkit/blob/main/lib/screens/add_policy.dart
You have two opptions:
have a global widget for appbar and use it on each different page,
or
You can have one Scaffold in your main.dart and instead of generating a new one for each page, only change the body parameter using setState. for example:
// have as many widget as you want for each page
const body1 = Text("body1"); //just a simple example, you can change it to whatever you want.
const body2 = Text("body2");
return Scaffold(
appBar: AppBar(
title: const Text('Sample Code'),
),
body: handleBody(selectedIndex)
);
then you can have a function to handle bodies:
handleBody(int index){ // you can pass different input for body selection I have used an int for simplicity
if(index == 1){return body1;}
if(index ==2) {return body2;}
// and so on
}
now with changing the selectedIndex you can show different bodies. Personally, I prefer to have a list of widgets and select one of them based on selectedIndex.

How to set default text style for appbar title in Flutter?

I have a lot of screens that have an app bar, I always have to set the style for the app bar each time I create a new screen, it so boring. So, anyone knows how to set a custom app bar text style or if there is a solution to this problem?
So you can do is create a method Method as mentioned below and then pass the value to it and later you just call these method where you want just check the code below:
you make another helper_widgets.dart and add the below method so that you can access it everywhere.
Widget appBar(String title,/* you can pass various paramenters to appbar text customization such as fontsize and many more*/ ) {
return AppBar(
title: Text(
title,
style: TextStyle(color: Colors.red, fontSize: 14),
),
);
}
and later just call it in the AppBar Widget
Scaffold(
appBar: appBar('Sample Application'),
);
Let me know if it works.

How can you set title and icon for a flutter web app?

What I'm trying to do is build a flutter web app that, when displayed in the browser, the tab shows an icon and a title (as currently it only shows the world icon and the localhost... title).
Actual Result :
Desired Result :
Edit:
I can now add the title, as this is set in the main function
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Icon(Icons.menu, color: Colors.white,),
title: Text(_your title here_),
)
...
);
}
So, the only thing I need to edit is the favicon
In order to change the title to what you desire, you need to add the parameter title (Which is a String) to your MaterialApp widget.
return MaterialApp(
title: "MyTitle",
home: MyHomeWidget());
Assuming you already have a favicon.ico file, placing it inside the your_project_dir\web folder alongside index.html as shown below is enough for the browser to pick it up.
Following is the result of placing a favicon.ico' in theweb` folder. Make sure to do a clean build.
In other case you can manually mention it using the link tag inside your index.html as explained here in this Wikipedia page.
Edit title
it is the simplest. just use the Title widget on each page or directly inside the materialApp constructor and set title string key to the title text you need.
like this:
...
Title(
color: myColors, //not important in web but still required
title: 'web page title',
child: myChildWidget,
),
...
Edit icon
If your app is only for the web, use the dart:html library to perform change using DOM access.
something like this
import 'dart:html';
...
...
updateIcon(String assetIcon){
LinkElement link = (document.querySelector("link[rel*='icon']") ??
document.createElement('link')) as LinkElement;
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = assetIcon;
}
if your application is multi-platform, you need to create separate main file for the web like main_web.dart. and declare the previous function inside this file.
Now, anywhere you need to set up the icon you just need to call the method after checking the platform using the keyword kIsWeb.
Ex: change icon inside page
...
initState(){
super.initSate();
if(kIsWeb){
WebMixin.updateIcon("assets/home_icon.png"); //WebMixin is just a helper. replace it by your one.
}
}
...
You could set the onGenerateTitle property of your MaterialApp widget, and provide a callback function to build your title. The onGenerateTitle callback is called each time the WidgetsApp rebuilds. This is useful if you want the title of your page to change dynamically or if you want to produce a localized title.
MaterialApp(
...
onGenerateTitle: (BuildContext context) {
return AppLocalizations.of(context).myTitle;
}
...
);
If you're wondering how to change the app name on your device's homepage, you can update the "name" and "short_name" values in web/manifest.json:
"name": "Ideasky",
"short_name": "Ideasky",

Flutter - how to get AppBar title foreground color

I have a Flutter app, where on the appBar, I have added a dropdown button. My app supports primary / secondary color changing.
The screenshot below shows an appBar for two different primary colors.
As you can see, the Flutter is able to decide what color to use for app bar text to keep proper readability - white for dark color and black for light color (second app bar).
I would like to set dropdown items' text color identical for the one, used by Flutter app bar text, hence, I would like to retrieve it.
Looking at Theme.of(context) properties, however, didn't give me a clue what color should I use to achieve what I need to.
Below is the code snippet:
final ThemeData _theme = Theme.of(context);
final int index = values.indexWhere((TimeSpan element) => element.value == initialValue.value);
return Theme(
data: _theme.copyWith(
canvasColor: _theme.primaryColor,
brightness: Brightness.dark,
),
child: DropdownButtonHideUnderline(
child: DropdownButton<TimeSpan>(
items: values
.map(
(value) => DropdownMenuItem(
child: Text(
value.toString(),
style: TextStyle(color: _theme.colorScheme.surface),
),
value: value,
),
)
.toList(),
onChanged: callback,
isExpanded: false,
value: values[index],
),
),
);
After a couple of days working with light / dark theme brightness, I figure out, a (possible) solution for the above case.
You can get the desired text color via one of the existing text themes, for instance Theme.of(context).primaryTextTheme.title.color returns color adjusted to current theme brightness.
Flutter renders the widget based on the final theme values it has.
So for example if the child widget has a different theme and the parent widget has a different theme, Flutter's rendering engine will first give preference to the child widget's theme over the parent widget's theme.
So DropdownButton has a theme hardcoded by default which cannot be directly changed as the widget does not accept any parameter to change the theme of the underlying widget(s) and as a result the Theme of the parent widget won't change/alter the theme of DropdownButton. That's the reason why the text Week remains black in both the cases.
If you really want to change the theme you can either alter the source code of DropDownButton or make a custom widget for it. However, simply hardcoding the values for text-color should still do the work.
In order to change the Appbar's text color you will have to manually change the text color as the parent theme suggests that the text color should be white whereas you want it to be black(as per your requirements).
Scaffold(
appBar: AppBar(
title: Text("Weight Overview",color: Colors.black)
)
[...]
)
On OP's request,
You can manually change the Theme of your children at any point of your Widget tree by using the Theme widget and providing it with a theme.
Solution code:
Scaffold(
appBar: AppBar(
title: Theme(
theme: ThemeData(primaryColor: Colors.black),
child: Text("Weight Overview",),
),
),
[...]
)

Removing the default back arrow on certain pages

From my understanding that a back arrow appears after navigating to any page by default. is there a way not to include the back arrow on a certain page of my choice ?
To hide the back button, set the automaticallyImplyLeading property of the Appbar as false
new Scaffold(
appBar: new AppBar(
automaticallyImplyLeading: false,
)
)
Duplicate of https://stackoverflow.com/a/44978595/3013538
I believe the solutions are the following
You actually either:
Don't want to display that ugly back button ( :] ), and thus go for :
AppBar(...,automaticallyImplyLeading: false,...);
Don't want the user to go back - replacing current view - and thus go for:
Navigator.pushReplacementNamed(## your routename here ##);
Don't want the user to go back - replacing a certain view back in the stack - and thus use:
Navigator.pushNamedAndRemoveUntil(## your routename here ##, f(Route<dynamic>)→bool);
where f is a function returning truewhen meeting the last view you want to keep in the stack (right before the new one);
Don't want the user to go back - EVER - emptying completely the navigator stack with:
Navigator.pushNamedAndRemoveUntil(## your routename here ##, (_) => false);
Cheers
According to AppBar docs
If the leading widget is omitted, ... Otherwise, if the nearest Navigator has any previous routes, a BackButton is inserted instead.
So you can hide it in such way
new Scaffold(
appBar: new AppBar(
title: new Text("Without back button"),
leading: new Container(),
),
);
Set automaticallyImplyLeading to false in AppBar or assign empty container in leading
Using automaticallyImplyLeading
appBar: new AppBar(
title: new Text("Your Text Here"),
automaticallyImplyLeading: false,
),
Using empty Container
appBar: new AppBar(
title: new Text("Your Text Here"),
leading: new Container(),
),
In case you want to remove the back button in a FloatingSearchBar, use
automaticallyImplyBackButton: false