How to set the background color of a Flutter OutlineButton?
To modify the backgroundColor of a OutlineButton you can use a DecoratedBox and a Theme widget. At the end of this answer you'll find a quick example.
Anyway I'd still recommend simply using the FlatButton with its color
attribute instead.
Wrap your OutlinedButton
inside a DecoratedBox
. Set the shape
of your DecoratedBox
to the same shape your OutlinedButton
. Now you can use the color
attribute of your DecoratedBox
to change the color. The result will still have a small padding around the OutlinedButton
. To remove this you can wrap the DecoratedBox
inside a Theme
in which you adjust the ButtonTheme
. Inside the ButtonTheme
you want to set materialTapTargetSize: MaterialTapTargetSize.shrinkWrap
.
The padding is added inside Flutter, to increase the tap area around the button to a minimum size of 48x48 (source). Setting materialTapTargetSize
to MaterialTapTargetSize.shrinkWrap
removes this minimum size.
FlatButton
example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: FlatButton(
color: Colors.pinkAccent,
shape: CircleBorder(),
onPressed: () => {},
child: Text('A'),
),
),
),
);
}
}
OutlinedButton
example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: MyButton(),
),
),
);
}
}
class MyButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DecoratedBox(
decoration:
ShapeDecoration(shape: CircleBorder(), color: Colors.pinkAccent),
child: Theme(
data: Theme.of(context).copyWith(
buttonTheme: ButtonTheme.of(context).copyWith(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap)),
child: OutlineButton(
shape: CircleBorder(),
child: Text('A'),
onPressed: () => {},
),
),
);
}
}
It is pretty much easy, just use
backgroundColor: MaterialStateProperty.all(Colors.colorname),
OutlineButton
has been deprecated and has been replaced with OutlinedButton
. (Notice the "d".)
OutlinedButton
's documentation helped me understand how to use it. Here's an example with these states: Disabled (Grey) --> Normal (Blue) --> Pressed (Red)
return Container(
width: double.infinity,
height: 48,
child: OutlinedButton(
child: Text(
"This is an Outline\"d\"Button. (Not OutlineButton)",
style: TextStyle(color: Colors.white),
),
onPressed: () => print("Tapped"),
//onPressed: null, //Uncomment this statement to check disabled state.
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>((states) {
if (states.contains(MaterialState.disabled)) {
return Colors.grey[100];
}
return Colors.blue;
}),
overlayColor: MaterialStateProperty.resolveWith<Color>((states) {
if (states.contains(MaterialState.pressed)) {
return Colors.red;
}
return Colors.transparent;
}),
side: MaterialStateProperty.resolveWith((states) {
Color _borderColor;
if (states.contains(MaterialState.disabled)) {
_borderColor = Colors.greenAccent;
} else if (states.contains(MaterialState.pressed)) {
_borderColor = Colors.yellow;
} else {
_borderColor = Colors.pinkAccent;
}
return BorderSide(color: _borderColor, width: 5);
}),
shape: MaterialStateProperty.resolveWith<OutlinedBorder>((_) {
return RoundedRectangleBorder(borderRadius: BorderRadius.circular(16));
}),
),
),
);
Flutter replaced the former 3 button types (FlatButton
, RaisedButton
and OutlineButton
) with new buttons types (TextButton
, ElevatedButton
and OutlinedButton
) to remain in sync with Material design and also because using MaterialStateProperty
provides the ultimate flexibility to achieve whatever state-specific-UI one needs. You can read more about it here.