RaisedButton vs ElevatedButton, FlatButton vs TextButton and OutlineButton vs OutlinedButton - flutter

I'm seeing the warning using old buttons:
'RaisedButton' is deprecated and shouldn't be used.
'FlatButton' is deprecated and shouldn't be used.
'OutlineButton' is deprecated and shouldn't be used.
So, what's the difference between:
RaisedButton and ElevatedButton
FlatButton vs TextButton
OutlineButton vs OutlinedButton

Here I found the docs for Migrating to the New Material Buttons and their Themes
The following image says itself what are the difference between all.
Visually, the new buttons look a little different, because they match
the current Material Design spec and because their colors are
configured in terms of the overall Theme’s ColorScheme. There are
other small differences in padding, rounded corner radii, and the
hover/focus/pressed feedback.
You can check Changes Overview for more about changes.

First are obsolete classes.
Quotes from the Flutter documentation:
FlatButton, RaisedButton, and OutlineButton have been replaced by TextButton, ElevatedButton, and OutlinedButton respectively.
The original classes will be deprecated soon, please migrate code that uses them.

These are obsolete classes, so eventually your old code needs to go away. (and, this document will help you do exactly that.) However, that can be a lot of work, so to get things moving, I created some code to migrate the FlatButton and RaisedButton to the new TextButton and ElevatedButton 'in place'. They are analogous to each other, but they approach styling in different ways, which this code handled.
Here's a link to the the gist if you want to run it in dartpad.dev (I couldn't get it to link directly):
https://gist.github.com/wterrill/7942b4bf5d74a8b2ace952ebf213fe5d
Here's the code itself:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final bool disableButton = true; // <-- Change this to see buttons disabled
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FlatButton(
child: Text("FlatButton"),
onPressed: disableButton
? null
: () {
print("FlatButton normal");
},
color: Colors.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
side: BorderSide(color: Colors.purple, width: 3.0)),
disabledColor: Colors.grey,
disabledTextColor: Colors.pink),
SizedBox(height: 25),
FlatButtonX(
childx: Text("TextButton"),
onPressedx: disableButton
? null
: () {
print("FlatButtonX (TextButton)");
},
colorx: Colors.green,
textColorx: Colors.black,
shapex: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
side: BorderSide(color: Colors.purple, width: 3.0)),
disabledColorx: Colors.grey,
disabledTextColorx: Colors.pink),
SizedBox(height: 100),
RaisedButton(
child: Text('RaisedButton'),
color: Colors.green,
textColor: Colors.black,
onPressed: disableButton
? null
: () {
print("RaisedButton normal");
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
side: BorderSide(color: Colors.purple, width: 3.0)),
disabledColor: Colors.grey,
disabledTextColor: Colors.pink,
),
SizedBox(height: 25),
RaisedButtonX(
childx: Text('ElevatedButton'),
colorx: Colors.green,
textColorx: Colors.black,
onPressedx:disableButton
? null
: () {
print("RaisedButtonX (ElevatedButton)");
},
shapex: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
side: BorderSide(color: Colors.purple, width: 3.0)),
disabledColorx: Colors.grey,
disabledTextColorx: Colors.pink,
)
],
),
),
),
);
}
}
Widget FlatButtonX(
{Color colorx,
#required Widget childx,
RoundedRectangleBorder shapex,
#required Function onPressedx,
Key keyx,
Color disabledColorx,
Color disabledTextColorx,
Color textColorx}) {
if (disabledTextColorx == null && textColorx == null) {
disabledTextColorx = colorx;
}
if (textColorx == null) {
textColorx = colorx;
}
return TextButton(
key: keyx,
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith<Color>(
// text color
(Set<MaterialState> states) => states.contains(MaterialState.disabled)
? disabledTextColorx
: textColorx,
),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
// background color this is color:
(Set<MaterialState> states) =>
states.contains(MaterialState.disabled) ? disabledColorx : colorx,
),
shape: MaterialStateProperty.all(shapex),
),
onPressed: onPressedx as void Function(),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0), child: childx));
}
Widget RaisedButtonX(
{Color colorx,
#required Widget childx,
RoundedRectangleBorder shapex,
#required Function onPressedx,
Key keyx,
Color disabledColorx,
Color disabledTextColorx,
Color textColorx}) {
if (disabledTextColorx == null && textColorx == null) {
disabledTextColorx = colorx;
}
if (textColorx == null) {
textColorx = colorx;
}
return ElevatedButton(
key: keyx,
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith<Color>(
// text color
(Set<MaterialState> states) => states.contains(MaterialState.disabled)
? disabledTextColorx
: textColorx,
),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
// background color this is color:
(Set<MaterialState> states) =>
states.contains(MaterialState.disabled) ? disabledColorx : colorx,
),
shape: MaterialStateProperty.all(shapex),
),
onPressed: onPressedx as void Function(),
child: childx);
}

One of the advantages of ElevatedButton over RaisedButton is that it will actually pick up your main theme color by default.
So you don't even need to add that custom background color. You would only need to bring your own styling in ElevatedButton, if you want to deviate from your main theme or style other aspects of the button.

My understanding is that they are really equivalent. According to the Flutter 1.22 announcement, the main motivation was around styling. Prior to Flutter 1.22, there was only ONE ButtonTheme for 3 types of buttons, whereas now each type of button has its own theme.

The FlatButton, RaisedButton and OutlineButton widgets have been replaced by TextButton, ElevatedButton, and OutlinedButton respectively.
Link explaining changes:
https://flutter.dev/docs/release/breaking-changes/buttons
How to use the buttons:
https://flutter.dev/docs/development/ui/widgets/material

you can't set borderSide nor shape either on OutlinedButton even though you could on OutlineButton

Alternative buttons such as TextButton, ElevatedButton, and OutlinedButton are not quite easy like before. We can still use those legacy buttons using the legacy_buttons package
https://pub.dev/packages/legacy_buttons/

Related

Is it possible to change Icon according to lightTheme or darkTheme in ThemeData? in flutter

I want the icon to change and the boxshadow color to change when GestureDetecotr is pressed. hopefully it will be What should I do?
In the current emulator, press the middle button to change the appearance.
blackMode
lightMode
home.dart part
import 'package:flutter/material.dart';
import 'package:neumorphism/theme/theme_service.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
bool _tapped = false;
var _lightIcon = Icons.wb_sunny;
var _blackIcon = Icons.dark_mode;
return Scaffold(
appBar: AppBar(
title: Text('Neumorphism'),
),
body: Center(
child: GestureDetector(
onTap: () {
ThemeService().changeThemeMode();
},
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(
Radius.circular(40),
),
boxShadow: [
BoxShadow(
color: Colors.grey.shade500,
offset: Offset(5.0, 5.0),
blurRadius: 15.0,
spreadRadius: 1.0),
BoxShadow(
color: Colors.white,
offset: Offset(-5.0, -5.0),
blurRadius: 15.0,
spreadRadius: 1.0),
]),
child: Center(child: Icon(_lightIcon)))),
),
);
}
}
themes.dart
import 'package:flutter/material.dart';
class Themes {
final lightTheme = ThemeData.light().copyWith(
primaryColor: Colors.grey[300],
appBarTheme: AppBarTheme(
brightness: Brightness.light,
),
iconTheme: IconThemeData(color: Colors.white, size: 80),
);
final darkTheme = ThemeData.dark().copyWith(
primaryColor: Colors.grey[800],
appBarTheme: AppBarTheme(
brightness: Brightness.dark,
),
iconTheme: IconThemeData(
color: Colors.black87,
size: 80,
),
);
}
theme_service.dart
theme_service.dart
Hello its easy to do this.
Your main problem is that you need to change the icons when the button is pressed. Right?
Then for this you have to use a Stateful Widget and then wrap the widget into a Value Listenable Builder. After that in onpressed you need to update the notifier.
Let's take a example....
Suppose you have to change the background color of the container when theme changed then do like this..
First create a Instance of value Notifier.
ValueNotifier<bool> _themeNotifier = ValueNotifier<bool>(false);
And then update the notifier in onpressed like this:-
onPressed:(){
_themeNotifier.value = false ; //update the value
}
Note that i have used bool as a datatype of value notifier but you can choose whatever suits your need.
Then Wrap your widget in a ValueListnablebuilder
ValueListenableBuilder(
valueListenable: _themeNotifier,
builder: (context, value, child){
return Container(
decoration:BoxDecoration(color:_themeNotifier.value ? Color.white : Color.black),
child: Container(),
)
},
),
Similar to this in you case you need to change the icon and boxshadow
according to the value of the notifier.
If you need any further explanation or help then you can comment.
and as always
Happy Coding...
you also need to change the brightness of context along with theme mode
Check your theme's brightness to change icon and shadows.
To change the icon, you can use this package. Install the package in your project, import it in your file and then simply replace the child of your container with the below code:
AdvancedIcon(
icon: Icons.wb_sunny,
secondaryIcon: Icons.dark_mode,
state: Theme.of(context).brightness==Brightness.dark ? AdvancedIconState.secondary : AdvancedIconState.primary,
)
Now to change shadow of the container, just replace the boxShadow of your container's decoration with below code:
// replace the shadow with your values.
Theme.of(context).brightness == Brightness.dark ? [BoxShadow(color: Colors.white)] : [BoxShadow(color: Colors.black)]

The argument type 'Color?' can't be assigned to the parameter type 'Color'

class _CreateRoomButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
// ignore: deprecated_member_use
return OutlineButton(
onPressed: () => print('Create Room'),
color: Colors.white,
borderSide: BorderSide(width: 3.0, color: Colors.blueAccent[100]),
textColor: Palette.facebookBlue,
child: Row(
children: [
Icon(
Icons.video_call,
size: 35.0,
color: Colors.white,
)
],
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
);
}
}
I have used an Outline Button in which I wanna set the border color to blueAccent[100]. On trying to do so the following error comes up :
The argument type 'Color?' can't be assigned to the parameter type 'Color'.
Also I wanna shift the outline button into the new Outlined Button but I am unable to style that acc to the app.
If you see Colors.blueAccent[100] actually gets a value from map. So if your version of flutter is bellow 2.0 you would get this error since it may return a null value.
Now why did this happen: This is because if you are using flutter 2.2 which is by default null-safe. You will get many errors.
Solution : Colors.blueAccent[100]! or Colors.blueAccent.shade100;
For OutlinedButton:
OutlinedButton.icon(
label: Text('MY BUTTON'),
icon: Icon(Icons.video_call),
onPressed: () {
print('Pressed');
},
style: OutlinedButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors.teal,
shape: const RoundedRectangleBorder(borderRadius:
BorderRadius.all(Radius.circular(30))),
),
)
You can tap into more properties : From here or you can see this Material Guidelines or this blog This Blog
you have updated flutter sdk i think and using null safety feature. just add ! after color.
color: Colors.blueAccent[100]!,
Note : Outlinebutton is deprecated use outlinedbutton instead.
Flutter Outlinedbutton

Hide Elevation Button shadow when I tapping on it

How can I hide ElevatedButton shadow, when I tapping on it. Or maybe I can use some differnt button, I need property to change shadow color and elevation. I tried to use ElevationButton(but it doesn't hide shadow when I tapped on it, on the contrary shadow becaming bigger). I alse tried to use RaisedButton, but it doesn't have property for changing shadow color.
ElevatedButton(
onPressed: (){},
style: ElevatedButton.styleFrom(
shadowColor: Colors.transparent,
),
child: Container(),
),
You can also use RawMaterialButton
Found solution, you just need to oveeride elevation in ButtonStyle with MaterialStateProperty, and set other parametrs as you need.
ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(activeColor),
overlayColor: MaterialStateProperty.all<Color>(pressedColor),
shadowColor: MaterialStateProperty.all<Color>(shadowColor),
padding:
MaterialStateProperty.all<EdgeInsetsGeometry>(EdgeInsets.zero),
shape: MaterialStateProperty.all<OutlinedBorder>(border),
elevation: MaterialStateProperty.resolveWith<double>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
return 0;
}
if (states.contains(MaterialState.focused)) {
return elevation;
}
if (states.contains(MaterialState.hovered)) {
return elevation;
}
return elevation;
}),
),
onPressed: onPressed,
child: textBody,
),

How to change the onPressed elevation in ElevatedButton Flutter

Before version 2.0.1 of flutter I was using the RaisedButton and there was a property called focusElevation to change the elevation of the button for when it was pressed. So after deprecating it by Flutter and according to the documentations we should use the ElevatedButton instead. But now I can't find a way to change it with the style: property.
I know how to change the elevation but I want to change the onPressed elevation for when user presses it. As comes from its documentations there are some default values for it:
The button's elevations are defined relative to the elevation parameter. The disabled elevation is the same as the parameter value, elevation + 2 is used when the button is hovered or focused, and elevation + 6 is used when the button is pressed.
So any idea how to customize the onPressed elevation in ElevatedButton?
You can do it using the style property.
ElevatedButton(
style: ButtonStyle(
elevation: MaterialStateProperty.resolveWith<double>(
(Set<MaterialState> states) {
// if the button is pressed the elevation is 10.0, if not
// it is 5.0
if (states.contains(MaterialState.pressed))
return 10.0;
return 5.0;
},
),
),
)
Or you can combine it with the new ElevatedButton.styleFrom() property, by usign the merge method. Like this:
ElevatedButton.styleFrom(primary: Colors.red).merge(
ButtonStyle(
elevation: MaterialStateProperty.resolveWith<double>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed))
return 10.0;
return 5.0;
},
),
),
),
),
final ButtonStyle raisedButtonStyle = ElevatedButton.styleFrom(
onPrimary: Colors.transparent,
primary: Colors.transparent, // transparent
padding: EdgeInsets.symmetric(horizontal: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(25)),
),
).merge(
ButtonStyle(elevation: MaterialStateProperty.resolveWith<double>((Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) return 16; // 点击时阴影隐藏
return 0; // 正常时阴影隐藏
})),
);
ElevatedButton(
style: raisedButtonStyle,
onPressed: () {
},
child: Text("click"),
)

How to achieve rounded corners on new OutlinedButton widget in Flutter?

With Flutter 1.22 we received a new widget OutlinedButton which is made to replace OutlineButton but how we can actually make its border rounded? borderSide and shape properties are not available anymore.
You can use OutlinedButton.styleFrom property:
OutlinedButton(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
side: BorderSide(width: 2, color: Colors.green),
),
onPressed: () {},
child: Text('Button'),
)
From the source code
/// All parameters default to null, by default this method returns
/// a [ButtonStyle] that doesn't override anything.
///
/// For example, to override the default shape and outline for an
/// [OutlinedButton], one could write:
///
/// ```dart
/// OutlinedButton(
/// style: OutlinedButton.styleFrom(
/// shape: StadiumBorder(),
/// side: BorderSide(width: 2, color: Colors.green),
/// ),
/// )
/// ```
Screenshot:
If you need some extra control over the style like border should be ABC when the button is pressed, DEF when its hovered... XYZ when not interacted, you can use ButtonStyle.
OutlinedButton(
onPressed: () {},
style: ButtonStyle(
shape: MaterialStateProperty.resolveWith<OutlinedBorder?>((states) {
// Rounded button (when the button is pressed)
if (states.contains(MaterialState.pressed)) {
return RoundedRectangleBorder(borderRadius: BorderRadius.circular(20));
}
}),
),
child: Text('OutlinedButton'),
)