How can I disable the default splash/ripple/ink effect on a Widget? Sometimes the effect is unwanted, such as in the following TextField case:
You can't disable inkwell in flutter, use an if condition to either display an inkwell or a container (without gesture handling properties) depending on the number of views the user has.
The simplest way to create a button with icon and text in Flutter is to use the new Material button called ElevatedButton with an icon constructor. ElevatedButton. icon() gives you the ability to add the icon and label parameter to the button. The ElevatedButton was introduced with the release of Flutter v1.
Flutter's InkWell class The InkWell class is a rectangular area of a Material widget that responds to touch events by displaying a clipped splash. The Material widget is responsible for the ink effects that are displayed when a touch event occurs. The Material refers to the area where the ink reactions are painted.
To disable the splash effect in BottomNavigationBar, wrap it in a Theme widget, and override the values of splashColor and highlightColor with Colors. transparent.
Per @hunter's suggestion above, I found that by setting both highlightColor
and splashColor
in my theme to Colors.transparent
removed the ripple.
I do hold some concerns that setting highlightColor
might have some knock-on effects, but I haven't noticed any yet.
Edit: While my original answer has loads of up-votes, the more I learn, the more I've realised that it really isn't the right way to do it. As several people have pointed out below, a better solution is to use the splashFactory
. For example, the code below shows it being set directly via the style, or you can set it in your theme too:
ElevatedButton( onPressed: onPressed, style: ElevatedButton.styleFrom( splashFactory: NoSplash.splashFactory, ), child: child, );
You can wrap the component into Theme
and set the properties splashColor
and highlightColor
to transparent on ThemeData
Theme( data: ThemeData( splashColor: Colors.transparent, highlightColor: Colors.transparent, ), child: YourWidget(), );
You can replace the Theme's splashFactory
with one that doesn't paint anything:
class NoSplashFactory extends InteractiveInkFeatureFactory {
const NoSplashFactory();
@override
InteractiveInkFeature create({
MaterialInkController controller,
RenderBox referenceBox,
Offset position,
Color color,
TextDirection textDirection,
bool containedInkWell = false,
Rect Function() rectCallback,
BorderRadius borderRadius,
ShapeBorder customBorder,
double radius,
VoidCallback onRemoved,
}) {
return NoSplash(
controller: controller,
referenceBox: referenceBox,
);
}
}
class NoSplash extends InteractiveInkFeature {
NoSplash({
@required MaterialInkController controller,
@required RenderBox referenceBox,
}) : assert(controller != null),
assert(referenceBox != null),
super(
controller: controller,
referenceBox: referenceBox,
);
@override
void paintFeature(Canvas canvas, Matrix4 transform) {}
}
And wrap your widget with it:
child: new Theme(
data: new ThemeData(splashFactory: const NoSplashFactory()),
child: new TextField(...),
),
Originally answered by HansMuller on a GitHub PR.
Set to a theme
final yourTheme = ThemeData.light();
...
Theme(
data: yourTheme.copyWith(
splashFactory: NoSplash.splashFactory,
),
...
)
Set to a material widget
ElevatedButton(
style: ElevatedButton.styleFrom(
splashFactory: NoSplash.splashFactory,
),
onPressed: () { },
child: Text('No Splash'),
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With