How to show Snackbar without Context object in flutter? - flutter

There are many times where we would have had separation of concerns when it comes to UI code and business logic. This is reflected in most of the state management solutions that we use in Flutter.
In many of the state management solutions where the business logic is outside the view file ( widget file) , there are cases where we want to show the snackbar based on the logic in flutter.
But to show a Snackbar we first need a context object. I have used a NavigatorState to navigate without context. But I don't know if there is a way to show SnackBar without context.
Can someone provide a solution for this ?
Also it would be very helpful if you could provide a Utility method that manages the state internally and whenever user wants to show snackbar would just call that utility method from his logical part of code.

You can specify scaffoldMessengerKey as a property of MaterialApp and then ScaffoldMessenger can be directly used without BuildContext.
I think you can do the same way as navigatorKey.
ref: https://api.flutter.dev/flutter/material/MaterialApp/scaffoldMessengerKey.html
Check this answer for more details on how to implement this into your application, with some code examples.

You definitelly can show a piece of information without a context, something similar to a snackbar, however, it is not a snackbar.
If you use the package Get, you can navigate without context, open dialogs, snackbars or bottomsheets from anywhere in your code. However, the snackbars in particular have some issues.
As it doesn't check for a Scaffold, the snackbar is shown directly in the bottom of your screen. This means that if you have a BottomNavigationBar, it will be covered or partially covered by it.
It also means that if you have a FloatingActionButton, it won't be responsive to the snackbar position, as opossed to the normal snackbar.
So to sum up, with Get, you can have snackbars without context but you will have to make some sacrifices in your UI.
Example
final bottomSnackBar = GetBar(
isDismissible: false,
showProgressIndicator: true,
message: 'Processing...',
);
bottomSnackBar.show();
somethingAsync().then((_) => bottomSnackBar.hide());

Related

how to send a data from page to another without change the screen?

i have a page named displayData . On it there is a button if i click on it it shows DraggableScrollableSheet normally it has a button done when i click on it the icon of the page on the bakground (DisplayData) must change .i used a variable in a setState but it doesn't work it's true on the DraggableScrollableSheet but always false in display data
any help !
for this type of cases, there are several solutions, I recommend the use of providers, in this way with the use of 'extends ChangeNotifier' you will be able to detect the changes made without having to use the setState and you will be able to call from any class (or page ) the variables you need
you can use callback methods from on widget to another, if you have much complicated scenario then I suggest using state management libraries like Provider, RiverPod or Bloc.
also
Could you share your code here

Trigger a function in TabBar based on a Floating button from parents

I am using flutter for my app.
I have a TabBarView that I would loop as shown as below.
TabBarView(
controller: controller,
children: visibleTab
.map((e) =>
TabDataWidget(
data: e,
)
).toList(),
);
Each Tab would be populated by the TabDataWidget (as shown above).
I have a Floating button, that I wanted to trigger a function inside the TabDataWidget when the user click at the Floating button.
If the user scroll to Tab Index 1, when the user clicks at the Floating button, I wanted to call a function inside TabDataWidget to process data inside Tab Index 1. Similarly, if the user scrolls to Tab Index 2, when the user clicks at the Floating button, I wanted to call a function inside TabDataWidet.
How can I achieve this in Flutter?
It seems like you need a state management solution as you want to access your data/methods from several widgets. Having a widget calling another widget's function to change state is not recommended as it can get messy and difficult to manage your state. Instead you should lift your state up in the hierarchy and use this state across the widgets you want. Flutter Docs have a great article that explains how you can approach state management. Different solutions exist but you might have a look at the provider package. Also there is a useful talk by the Flutter team explaining common anti patterns and how provider can help to overcome these.

How to check visibility of a Flutter widget even when covered by another

I'm trying to find a way to check the visibility of a Flutter widget when it's either off screen or when it's obscured by another, for example Drawer, Dialog or BottomSheet.
visibility_detector helps with checking whether it's on the screen or not but does not work with the second use case (known limitation).
Is there a lower lever api that I can use to check whether a widget is actually visible to the user?
My use case: I'm adding a widget to the Overlay when something external happens (similar to Tooltip but not on long press). If the user opens for example the Drawer, the widget will appear on top. I want to detect that the child is not visible and delay or cancel the action.
Do I understand your problem?
You have a widget you want to always be on top?
You want the user to interact with that widget first before doing other things?
Use design patterns to make coding easier, your users will thank you.
You can show a Dialog on-top of other widgets with the showGeneralDialog or showDialog functions. Because Dialogs are a design-pattern used in many apps, users will already know how to use them.
Define app behavior with explicit state.
It is too hard to derive app behavior from rendered UI, not all devices are the same size and shape. This means you should try to write a variable that describes your situation and then write the code you need to make that variable's value correct. It sounds like you want a variable like bool overlayIsShowing.

Preserving the State of a Drawer in Flutter

I have a stateful Scaffold widget, where the body contains a list of entities with various properties (e.g. shoes or cars) and Drawer widget, which is empty at first, except for two buttons at the bottom ("Cancel" and "Filter") and a FAB. The user can add various filters with the FAB (e.g. the user can add a shoesize-filter, or a color-filter).
The problem I have is the following: Let's say the user selects various filters and works with them (i.e. ticks checkboxes, enters a shoesize, changes sliders, etc.). When the user is ready to apply the filters, he can click the "Filter" button, which closes the Drawer (onTap -> callback -> Navigator.of(context).pop()). But when the user wants to go back, reopen the Drawer, and adjust one of the filters, it obviously doesn't work, since the widget is being rebuilt from scratch.
Currently, the way the filtering works is, once the "Filter" Button is pressed, all the various values from the added filters are collected into an object FilterPackage, which is then passed via callback to the Scaffold widget, which then applies the values from the FilterPackage to the list of entities.
One solution I came up with, would be feeding this FilterPackage object to the Drawer widget in its constructor, which would provide all the information necessary to rebuild the widget just how it has to be.
Is that a reasonable solution? I have already made some research, but struggled finding a solution on what would clearly be the best and recommended way to preserve the drawer's state. Using PageStorage / PageStorageBucket seems overly complicated for this case. Or am I wrong?
Thanks in advance for any guidance.

In Flutter does avoiding setState() achieve anything?

In Flutter does avoiding setState() achieve anything?
I have a StatefulWidget (screen) where I use Widgets that handle their own state completely with the exception of the FAB button. The Fab button is disabled or enabled when data has changed in order to allow the update of the DB when data has changed. I posted a question on SO as to how to use Provider to handle that and thus prevent the need to setState(), and implemented that with Provider.
When looking at another screen to implement something similar, I wondered if another solution may be better. This screen also contains Widgets that all handle their own state - TextFields with TextEditControllers, so the only place I was calling setState() was to enable or disable the FAB. I had previously created a Stateful Widget to create a CheckBox with its own state because the standard CheckBox doesn't have state. It's fairly simple and only 50 lines of code. So, I did the same with the FAB, I created a Stateful Widget (CustomFab) that encapsulates a FAB. When it needs to be enabled or disabled, it is called to set its own state, and returns a FAB that is either enabled or disabled with the appropriate color. Because I have other similar screens, I can use that same component with them.
Does it achieve anything by avoiding setState() in this situation (for mobile and Web), and if so, which is the best way to handle that (Custom-Widget or Provider or another)?
setState is merely avoided in Flutter development for two main reasons:
It rebuilds the whole widget, which may hinder performance on consecutive calls if not used correctly.
using setState only as a state management couples the business logic to the UI, which may reduce code re-usability and maintainability.
In simple apps, there are no significant issues in using setState. However, if you need more control over your code, I suggest going for more complex state management patterns.