flutter_speed_dial icon indicating copy to clipboard operation
flutter_speed_dial copied to clipboard

Flickering the color of the FAB when you click on it

Open yegor-pelykh opened this issue 1 year ago • 11 comments

The color of the button flickers during the open/close state switching. This greatly spoils the impression of its use. Especially when using the dark theme.

Peculiarities:

  • for me it is relevant ONLY when use Flutter Web (also tested on Windows - it works correctly)
  • it is relevant even in simplest use cases
  • it does not depend on whether an animatedIcon is used on the SpeedDial
  • this effect is especially noticeable when using a dark theme and dark FAB colors

I recorded a short video demonstrating this effect. It is not always visible on the video, but in reality the effect is always reproduced when the state is switched. https://user-images.githubusercontent.com/21262076/196223806-983e5e80-0a77-453d-9a1b-b80654db577c.mp4

This is very annoying. Could you please have a look?

yegor-pelykh avatar Oct 17 '22 15:10 yegor-pelykh

That is not flicker but splash color which is present in every Floating action button

prateekmedia avatar Oct 18 '22 01:10 prateekmedia

Maybe I did not quite understand your point of view, but I set the splash color (black) to the application theme, but it still flickers light, it seems pure white.

MaterialApp(
    darkTheme: ThemeData(
        ...
        splashColor: Colors.black,
    ),
    themeMode: ThemeMode.system,
)

Also, given that this is only relevant for the web, it looks strange. Therefore, this is not a splash color.

yegor-pelykh avatar Oct 18 '22 10:10 yegor-pelykh

New clarification: this flicker is not present if the property renderOverlay of SpeedDial is false. Which clarifies a bit that the problem is using the overlay. But unfortunately I need overlay too.

UPD: when renderOverlay: true and overlayColor: Colors.red, the control flickers in any case in white, regardless of the color of the overlay.

UPD2: when renderOverlay: true and overlayOpacity: 0, it does not just flicker, but switches to a completely recolored white control, and remains in the same state. It's probably best for you to see it for yourself.

None of these problems are reproduced on Windows and Android, only on Web.

yegor-pelykh avatar Oct 18 '22 11:10 yegor-pelykh

Basically, I have already found the cause of the problem.

This place: https://github.com/darioielardi/flutter_speed_dial/blob/c01d6d94db849bcfd1f543fbed953650eb624b73/lib/src/background_overlay.dart#L62

If we put a different color there, all those flickers and repaints will now be in that color.

In fact, I would advise putting there the color in which the fab is currently painted, but not white. But how best to do this is probably better for you to decide.

I tried to put there the color used for FAB in my app (the default primaryContainer color), and it looks ok.

yegor-pelykh avatar Oct 18 '22 12:10 yegor-pelykh

This problem is valid, I also have a permanent and reliable solution which would solve this but we need more contibutors.

If you are interested in fixing this then please read: https://github.com/darioielardi/flutter_speed_dial/discussions/253, I will be ready to help if you need in implementing it.

prateekmedia avatar Oct 18 '22 13:10 prateekmedia

The problem with using flutter_portal here is that it requires you to add their own Portal widget to the widget tree, above the Scaffold. That is, each user who installs the SpeedDial package must be forced to do it on their own, since the package itself cannot do this.

yegor-pelykh avatar Oct 18 '22 17:10 yegor-pelykh

@yegor-pelykh Yes but it will only work like that only, Having it over the nearest Scaffold also works. Maybe we can create an extension for Scaffold like Scaffold.sd() which would work just like normal scaffold but it will have Portal wrapped over it.

What do you think about this?

prateekmedia avatar Oct 19 '22 04:10 prateekmedia

Yes, probably in the case of using this package, it could be done in this way. But...

Yesterday I tried to deal with this flutter_portal, also with your widget. But unfortunately I don't see now a way to do all this with flutter_portal. In fact, I don't even see the benefit this package will give you over what you already have. As I understand it, these are the same overlays, but declared differently. I honestly don't see how this package can improve the situation. Which was confirmed by my unsuccessful attempts yesterday. The fact is that, as I understand it, the main problem here is not how to set the overlay, but that any overlay will either not be hit tested at all, or the whole will be hit tested, including the hole that you would like to make for the fab . But how that package can make that hole the way you want it to be? You will need to use the same techniques like HolePainter or ColorFiltered, as now, nothing progressive. Like here: https://www.flutterclutter.dev/flutter/tutorials/how-to-cut-a-hole-in-an-overlay/2020/510

In addition, now there is so much functionality in this widget that redesigning it to use this package will in any case entail a change in the entire implementation, code structure, and a complete revision of everything. In any case, all my attempts to apply this flutter_portal have been unsuccessful. Also, I don't really understand how it works. It seems to me that it will be a long time before someone can do it properly, considering that your widget can be located anywhere and is highly customizable.

Visually, now everything looks quite correct, except for this bug described above, and without using an additional package. I don't really know why do you want to use it.

But the problem with this color, which I indicated above, is relevant in the current implementation, so I would prefer to first deal with this problem in the current implementation (set the color there to actually match the one on the button) than to wait for such a massive rework, leaving now this problem for all Flutter Web developers. Especially since it's a bug anyway. I don't understand why it's WHITE. If you replace it with a correct color, this will not prevent you from further waiting for a massive rework with that package, once you want it 😉

Could you just try to fix this problem for now?

yegor-pelykh avatar Oct 19 '22 09:10 yegor-pelykh

How I see further fighting with the overlay:

  • either try to dig in the direction of making a real hole in the overlay, with the passage of mouse events through it, while this hole tracks the change in the position/size/shape of the fab after opening the overlay and changes its position/size/shape.
  • or put on top of the overlay exactly the same fab widget. The advantage is that you don't have to keep track of the original fab's position/size/shape, it will always match if you create it with the same fab creation function, i.e. SpeedDial._renderButton(). But at the same time, you need to create it with a different key, because flutter will not allow you to create a second widget on the screen with the same key, as far as I know.

yegor-pelykh avatar Oct 19 '22 11:10 yegor-pelykh

Basically, I have already found the cause of the problem.

This place:

https://github.com/darioielardi/flutter_speed_dial/blob/c01d6d94db849bcfd1f543fbed953650eb624b73/lib/src/background_overlay.dart#L62

If we put a different color there, all those flickers and repaints will now be in that color.

In fact, I would advise putting there the color in which the fab is currently painted, but not white. But how best to do this is probably better for you to decide.

I tried to put there the color used for FAB in my app (the default primaryContainer color), and it looks ok.

I am having the same issue and I can also confirm that it is coming from the same place.

shrijanRegmi avatar Dec 23 '23 02:12 shrijanRegmi

I was able to fix this by setting useRotationAnimation: false. I was not using the rotation animation so I could set that to false. Not sure how you'll fix this if you absolutely need the rotation animation.

shrijanRegmi avatar Dec 23 '23 02:12 shrijanRegmi