Reputation: 6798
In my app, I setup a IconButton to render over a Row with a color background. Unfortunately, the ripple animation on button press renders under the Row (as shown in the screencast). How do i make the ripple show over the Row?
class Card extends StatelessWidget {
final Issue issue;
Color _bgColor;
Card({this.issue}) {
_bgColor = colorSwatch[issue.hashCode % colorSwatch.length];
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 12, left: 18, right: 18),
padding: EdgeInsets.only(top: 8, bottom: 8),
decoration: new BoxDecoration(
color: _bgColor,
border: new Border.all(color: _bgColor),
borderRadius: BorderRadius.all(
Radius.circular(10.0)
),
),
child: Row(children: [
IconButton(
padding: EdgeInsets.only(right: 16),
icon: Icon(Icons.play_arrow, color: Colors.white, size: 48),
tooltip: 'Start ${issue.issueName}',
onPressed: () {},
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
issue.title,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
softWrap: true,
),
),
Text(
issue.issueName,
style: TextStyle(
color: Colors.white,
),
),
],
),
),
]));
}
}
Upvotes: 17
Views: 9626
Reputation: 2617
The ripple is part of the Material
effect. Wrap your IconButton
with Material
:
Material(
color: _bgColor,
child: IconButton(
padding: EdgeInsets.only(right: 16),
icon: Icon(Icons.play_arrow, color: Colors.white, size: 48),
tooltip: 'Start ${issue.issueName}',
onPressed: () {},
),
),
UPDATE
To be more specific to your goal, you can replace your Container
with Material
.
return Material(
color: _bgColor,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
child: Container(
margin: EdgeInsets.only(top: 12, left: 18, right: 18),
padding: EdgeInsets.only(top: 8, bottom: 8),
backgroundBlendMode: BlendMode.multiply,
child: Row(
...
),
);
Upvotes: 20
Reputation: 136
It looks like a bug in the Flutter Framework. This occurs only with IconButton, no problem with FlatButton.
Possible workaround is to set BlendMode to multiply BlendMode.multiply.
try this:
Container(
decoration: BoxDecoration(
color: Colors.greenAccent[400],
backgroundBlendMode: BlendMode.multiply),
child: ListTile(
leading: IconButton(icon: Icon(Icons.play_arrow), onPressed: () {}),
title: Text("issue title"),
subtitle: Text("description"),
),
),
Update
issue on github
Upvotes: 2
Reputation: 4933
Ripple always takes on top of the material widgets. So if there is anything on top of the material widget you will see ripples under your widget.
Just wrap your IconButton with a Material widget with the material set to use the "transparency" type and it should work.
You can use the below generic widget for adding ripples to your widgets.
class AddRipple extends StatelessWidget {
final Widget child;
final Function onTap;
AddRipple({@required this.child, @required this.onTap});
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
child,
Positioned.fill(
child: new Material(
color: Colors.transparent,
child: new InkWell(
onTap: onTap,
))),
],
);
}
}
You can also take in a color in the constructor and user 'splashColor' property of the InkWell widget to set the splash color.
Upvotes: 0
Reputation: 3653
You can wrap your Row
inside a InkWell
, this will give you the touch ripples.
I have removed the background color of the container, had issues with it showing the ripple, as well as changed the text color to black.
@override
Widget build(BuildContext context) {
return Container(
height: 100,
margin: EdgeInsets.only(top: 12, left: 18, right: 18),
padding: EdgeInsets.only(top: 8, bottom: 8),
decoration: new BoxDecoration(
color: Colors.transparent,
border: new Border.all(color: Colors.orange),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
child: InkWell(
// added here
onTap: () {},
child: Row(children: [
IconButton(
padding: EdgeInsets.only(right: 16),
icon: Icon(Icons.play_arrow, color: Colors.black, size: 48),
tooltip: 'Start issue',
onPressed: () {},
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
'issue.title',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
softWrap: true,
),
),
Text(
'issue.issueName',
style: TextStyle(
color: Colors.black,
),
),
],
),
),
]),
));
}
References
Upvotes: 0