Why don't the buttons in Flutter Web have a margin? - flutter

I have the following code:
Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {},
child: Text('Boton 1'),
),
ElevatedButton(
onPressed: () {},
child: Text('Boton 2'),
),
ElevatedButton(
onPressed: () {},
child: Text('Boton 3'),
),
],
),
),
)
Why on mobile do the buttons have a margin but on the web they do not?
Note: I know I can add padding/margin manually, set default button style, etc. I want to know why the default behaviour is different.

Quite an interesting question. Thanks for asking.
This is basically due to the ThemeData.materialTapTargetSize parameter for the MaterialApp.
This feature decides what should be touchable dimensions of Material Button, in your case ElevatedButton.
The difference in behaviour is due to this piece of code in flutter/lib/src/material/theme_data.dart at line no 377. flutter sdk: ">=2.12.0 <3.0.0"
switch (platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.iOS:
materialTapTargetSize ??= MaterialTapTargetSize.padded;
break;
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
materialTapTargetSize ??= MaterialTapTargetSize.shrinkWrap;
break;
}
The MaterialTapTargetSize.padded, make buttons take a height of 48. Whereas, the MaterialTapTargetSize.shrinkWrap does what it says and removes that constraint.
If you have your MaterialApp like this,
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
home: CupertinoPickerExample(),
)
Then the out put is,

Adding to #Nisanth Reddy's answer, you may also want to look at visualDensity, which is set also by defaultTargetPlatform here, as a result of this.
To ensure a consistent look across platfoms, I use the following -
MaterialApp(
...
theme: ThemeData(
...
materialTapTargetSize: MaterialTapTargetSize.padded,
visualDensity: VisualDensity.standard,
),
)

Related

How to put two IconButtons in the same Column (AppBar and Body)?

Is there any way how to have an IconButton in the AppBar and an IconButton in the Body the same column width? The splash radius should be default. Please have a look on a screenshot at the following link for an overview.
https://i.stack.imgur.com/O0CiM.png
I'm not sure if this is the solution that you are looking for, because your question is not clear 100%.
By default IconButton are aligned to the AppBar actions. You can check it on this sample:
https://dartpad.dev/?id=0199904cac2a477c420efe473ed21319
The result is this:
You can use SilverAppbar medium or large depend on you. This widget is new in flutter 3.3 so just update SDK to using it.
In MaterialApp you need to specify:
theme: ThemeData(useMaterial3: true)
And then in Scaffold body:
return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar.medium(
title: const Text('Your tittle of page'),
actions: [
IconButton(onPressed: () {}, icon: const Icon(Icons.abc)),
IconButton(
onPressed: () {}, icon: const Icon(Icons.abc_outlined)),
],
),
SliverToBoxAdapter(
child: Text('Content of page'),
),
],
),
);

how we can use two rows in appbar flutter Like first row with title and the second with search input field

Hi There I am working on a app where i need to use two sections in appbar one upper
1->section with logo and some Icons
2-> Search input field below the Title Section.
UI images are attached for better understanding.
you can customize the size of app bar by using toolbarHeight: 120.0 // set value
then use flexibleSpace to add column or rows
it will look something like this
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
toolbarHeight: 120.10, //set your height
flexibleSpace: SafeArea(
child: Container(
color: Colors.blue, // set your color
child: Column(
children: [
Row(
children: [Text("Logo")],
),
Text("data"), // set an icon or image
IconButton(
icon: Icon(Icons.search),
onPressed: () {}) // set your search bar setting
],
),
),
),
),
),
);
}
}
Just simply create your AppBar as intended, in your screenshot, you don't actually need a second Row. A TextFormField will be enough (you will actually need to customise the InputDecoration as well):
return AppBar(
title: Column(children: [
Row(children: [
Icon(Icons.menu),
Text('First row'),
const Spacer(),
Icon(Icons.person),
]),
TextFormField(),
]),
);
You can use the bottom property from the AppBar widget.
AppBar(
title: YourFirstRowWidget(),
centerTitle: true,
bottom: PreferredSize(
child: YourSearchBarWidget(),
preferredSize: null),
)
But you may want to create your own AppBar widget for a perfect result.

How can I change the textbutton color in the flutter showAboutDialog?

I'm using the showAboutDialog function from flutter to show used licences in my project. How ever I'm stuck with changing the text color of the VIEW LICENSES and CLOSE textbuttons. See this image for clarification:
This is my code:
...
onTap: () {
showAboutDialog(
context: context,
applicationName: 'bla',
applicationLegalese: 'November 2023',
);
},
What I tried so far is looking for a color field inside the showAboutDialog how ever I could not find anything. I'm assuming that I could change the color in my MaterialApp ThemeData. Unfortunately I was not able to find the specific theme to override the default styling of those textbuttons.
I tried the following in my MaterialApp ThemeData to change the color of VIEW LICENSES and CLOSE to green but that did not change anything:
textButtonTheme: TextButtonThemeData(style: ButtonStyle(foregroundColor: MaterialStateProperty.all<Color>(Colors.green))
Any ideas about this?
I was not satisfied with the answers here because all were showing only MaterialColor use-cases and I wanted a custom color. But I finally found something explaining it well on the following link.
https://blog.logrocket.com/new-material-buttons-in-flutter/
Basically, what is confusing is that the new design uses the primary color instead of the textStyle property. You can still apply the other answers to change the overall theme using a MaterialColor, and you can override the existing color theme using any color by using primary under TextButton.styleFrom.
Example for anywhere in the app:
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
foregroundColor: Colors.pink,
),
child: Text(
'TextButton (New)',
style: TextStyle(fontSize: 30),
),
)
Example for the theme:
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
primary: kDarkColor, // This is a custom color variable
textStyle: GoogleFonts.fredokaOne(),
),
),
You can use this:
return MaterialApp(
theme: ThemeData.dark().copyWith(
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith(
(state) => Colors.orange)))),
home: MyWidget(),
);
MaterialStateProperty.resolveWith takes a function, you can specify the color based on states, such as
MaterialState.pressed,
MaterialState.hovered,
MaterialState.focused,
More info on this.
How about this one?
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.green,
).copyWith(),
),
debugShowCheckedModeBanner: false,
home: YourScreen(),
);
}
i run this code.
after some research i find out this way to change colour.
for this you need to set application main theme colour change, like this
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.brown,//i am set brown colour,you can set your colour here
),
debugShowCheckedModeBanner: false,
home: YourScreen(),
);
}
after this its work,
showAboutDialog(
context: context,
applicationName: 'bla',
applicationLegalese: 'November 2023',
);
If you want to change the colors only for the dialog and not for the whole app, you have to create a new context. Surround the Button that showing the dialog with a Theme and a Builder
Theme(
data: Theme.of(context).copyWith(
colorScheme: colorScheme.copyWith(primary: Colors.green),
),
child: Builder(
builder: (context) {
return ListTile(
title: Text('show dialog'),
onTap: () => showAboutDialog(
context: context,
...)
);
},
),
)

Floating Action Button in Flutter

I was trying to create the Floating Action button but I am missing icon.
My code is:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
centerTitle: true,
title: Text(
"Lessons of Flutter",
style: TextStyle(
color: Colors.white,
),
),
),
body: Center(
child: const Text('Press the button below!')
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Add your onPressed code here!
},
child: Icon(Icons.mouse),
backgroundColor: Colors.green,
),
),
);
}
}
it is a screen from the virtual device.( You can see icon looks weird.)
To use this class, make sure you set uses-material-design: true in your project's pubspec.yaml file in the flutter section. This ensures that the MaterialIcons font is included in your application. This font is used to display the icons. For example:
Refer this link: https://api.flutter.dev/flutter/material/Icons-class.html
The Icon is not rendering because of the missing font from the material design library. You have to enable the material design library in your pubspec.yml file as given below,
flutter:
uses-material-design: true
Just make uses-material-design to true and the error will be gone. This ensures that the MaterialIcons font is included in your application. This font is used to display the icons Here is the official docs of Icon class

Changing the Bottom Navigation Bar when switching between screens in the body of a Scaffold

HomeScreen() function call the Home screen of App.
How I Can route/move to "Team", "Add", etcetera page without BottomNavigationBar and AppBar.
I want show another page and back button, with new Bottom Navigation Bar.
I have this on my Flutter Project:
class APPMain extends StatefulWidget {
#override
_APPMainState createState() => _APPMainState();
}
class _APPMainState extends State<APPMain> {
int _currentIndex = 0;
_onTapped(int index) {
setState(() {
_currentIndex = index;
});
}
#override
Widget build(BuildContext context) {
List<Widget> screens = [
HomeScreen(),
Center(child: Text("Team")),
Center(child: Text("Add")),
Center(child: Text("Search")),
Center(child: Text("Settings")),
];
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xffffffff),
iconTheme: IconThemeData(color: Colors.grey),
title: Text("Test App", style: TextStyle(color: Colors.grey),),
actions: <Widget>[
IconButton(
icon: Icon(Icons.account_circle),
onPressed: (){},
),
],
),
body: Container(
color: Color(0xfff4f4f4),
child: Center(
child: screens[_currentIndex],
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.red,
onTap: _onTapped,
items: [
BottomNavigationBarItem(
title: Text('Home'), icon: Icon(Icons.home)),
BottomNavigationBarItem(
title: Text('Team'), icon: Icon(Icons.group)),
BottomNavigationBarItem(
title: Text('Add'), icon: Icon(Icons.add)),
BottomNavigationBarItem(
title: Text('Search'), icon: Icon(Icons.search)),
BottomNavigationBarItem(
title: Text('Settings'), icon: Icon(Icons.settings)),
]),
);
}
}
Thank you so much for help.
This is almost certainly a duplicate but I wasn't able to find a question asking something similar with a quick search so I'll answer anyways.
The answer is actually quite simple, but requires understanding a bit more about how to write flutter applications - you should be using a Navigator or the navigator built right into MaterialApp or WidgetApp rather than making your own navigation. The simplest way is to use MaterialApp's routes property and pass in a map with each of your pages. Then when you want to switch pages, you simply use Navigator.pushNamed(context, <name>) from wherever you want to switch the page (i.e. a button).
The part that can be slightly confusing when you come from other frameworks is that rather than having one Scaffold and switching the body of it, the entire page should switch and each page should have a Scaffold.
Here's an example in the documentation showing how to navigate between pages.
For the record, although it's a bad idea you could make it work with your original code as well - all you'd have to do is build a different BottomNavigationBar with different options depending on what _currentIndex is set to. But I don't recommend that. With what I've suggested you also get animations between pages, back button functionality, you can hook up analytics to track page usage, and a bunch more things that flutter provides as part of navigation.