Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable default Widget splash effect in Flutter?

Tags:

flutter

widget

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:

like image 670
xip Avatar asked Apr 25 '18 10:04

xip


People also ask

How do I turn off InkWell in flutter?

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.

How do you make a text button in flutter?

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.

What is InkWell in flutter?

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.

How do I make Bottomnavigationbaritem not clickable and disable tap splash effect?

To disable the splash effect in BottomNavigationBar, wrap it in a Theme widget, and override the values of splashColor and highlightColor with Colors. transparent.


4 Answers

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, ); 
like image 58
Craig Edwards Avatar answered Sep 25 '22 13:09

Craig Edwards


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(), ); 
like image 20
Camilo Acosta Avatar answered Sep 25 '22 13:09

Camilo Acosta


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.

like image 43
xip Avatar answered Sep 23 '22 13:09

xip


Use NoSplash.splashFactory

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'),
)
like image 20
Alex.F Avatar answered Sep 23 '22 13:09

Alex.F