Widget wont refresh with setstate sfcalendar custom agenda - flutter

The Picture shows how it should look like.
But in my App, the agenda is inside a TAB!
Can anyone tell me why my code wont work?
I am trying to display data from DataSource but it wont show up!
(SFCalendar - Custom Agenda)
(Basically - to get it to show my appointments in a separate widget "far up the tree" <onTap: calendarTapped>)
I recreated the code on github since its too much code for stackoverflow - i guess its easier with vcs anyway:
https://github.com/panval/sfcalcustagenda.git
I simply can't manage to get it to work!
What am I missing?

You arent passing the selected item on Tabs widget. You can use constructor the way you did for CustomAgenda.
class Tabs extends StatefulWidget {
Tabs({Key? key, required this.appointmentDetails});
and use
CustomAgenda(appointmentDetails: widget.appointmentDetails),
You can remove the state variable from here.

Related

Add AppBar actions from Scaffold children such as from Fragment.onCreateOptionsMenu in Android (using InheritedWidget)

In Android, every Fragment can partecipate in populating the options menu (aka "appBar actions", in flutter terms) of the activity, using the Fragment.onCreateOptionsMenu callback.
I would like a similar mechanism also in flutter, i.e. that some widgets are able to add buttons ("actions") to the AppBar.
Threads had already been opened on this topic, but none reports a fully functional example and contains solutions to the precise technical problem I encountered.
To do this, I had thought of using the following 'typical' structure:
a StatefulWidget -to which I have given name ScaffoldHandler (ScaffoldHandlerWidget/ScaffoldHandlerState)- which wraps the entire Scaffold, and which uses InheritedWidget so that widgets further down the widgets tree can get a reference to it in an optimal way (using the classic of() method which executes dependOnInheritedWidgetOfExactType()).
ScaffoldHandlerState keeps in a field the actions set by the various children, and supplies them to the app-bar.
a widget that creates the AppBar. In the build() method it gets the actions to be displayed calling ScaffoldHandlerState.of().
mixin ScaffoldChild on State, which applied to a widget gives it the ability to add actions to ScaffoldHandlerState.
Internally, ScaffoldChild executes ScaffoldHandlerState.of() in didChangeDependencies() (to add actions) and in deactivate() (to remove them).
I originally used initState() and dispose() but this did not handle the case where a ScaffoldChild changes position while not being permanently removed from the widgets tree.
The problem I encountered is that ScaffoldAppBar.build is executed before ScaffoldChild.didChangeDependencies, so when the app-bar is created, ScaffoldChild still has to put its actions in ScaffoldHandlerState.
The curious thing is that this problem is due to the simple linear order in which ScaffoldAppBar and ScaffoldChild are inserted in the page: if instead of a top app-bar I want to create a bottom app-bar, the problem is not there because ScaffoldChild.didChangeDependencies would run before ScaffoldAppBar.build.
As a workaround to overcome the problem, I have inserted in ScaffoldChild.didChangeDependencies a call to scaffoldHandler.setState scheduled by WidgetsBinding.instance.addPostFrameCallback(): thus, after the actions have been inserted in ScaffoldHandler, the app-bar is updated with the new actions.
However, this solution seems like a hack to me.
In stackoverflow I see a lot of problems solved with addPostFrameCallback + setState, and sometimes that solution avoids really understanding where it goes wrong; I am interested in understanding if there are better solutions because my purpose, as well as practical, was to better understand the lifecycle of widgets.
Is there a better solution?
This is my code:
DartPad or Gist
(I tried to shorten it as much as possible, but sorry if it's not really short)

How to refresh Dialog when the data has change? Flutter

I'm a new Flutter developer and I have a problem, which I haven't been able to solve yet, even if I tried a lot.
I'm developing an App, where at some point a Dialog is opened(with showDialog()). In this Dialog there are 2 AutoCompleteTextField:
In the first one, the data will always be the same. So there is a list and the user needs to choose one of the choices. First AutoCompleteTextField code
In the second one, the data to be shown depends on the previous choice. In other words,
whenever an item from the previous list is chosen, the subdata of the item will be requested. Second AutoCompleteTextField code
The required data is fetched properly, however the dialog is not refreshing state so the suggestions of the second AutoCompleteTextField appears empty. When I close and enter again the suggestions of the second appears as they should.
To get notified when the data changes I use ChangeNotifier and Provider, but doesn´t refresh the Dialog (ChangeNotifier class). I also use StatefulBuilder to be able to use setState, but again, doesn´t refresh (Dialog code).
I would like to know if there is any other way to refresh the Dialog. Thank you!
PD: This is my first question in StackOverflow. I tried my best.
I think you need to use Provider.of(context) to be able to listen to the updates and refresh or add/update the data.
Provider.of(context)
I would create a widget class instead of the _widgetTask function and then use Provider.of(context) inside the widget build function like following (I think you can also try to add it inside the _widgetTask function but I dont know if this would work).
class WidgetTask extends StatelessWidget {
//WidgetTask contructor here..
#override
Widget build(BuildContext context) {
final odooData = Provider.of<OdooData>(context);
And then use the odooData to access the data/functions you need to update/listen to from the provider.
Also you can wrap the widget with GestureDetector so that you can update the widget upon tapping using the OnTap property.
flutterdartdialogrefreshproviderconsumer

Problem showing a value contained in an InheritedWidget

I've been developing in Flutter for a few months and I'm not yet very experienced. These days I'm working on an app that I didn't create from the beginning and I'm having a strange problem, unfortunately I can't paste too much pieces of code but I try to explain the wrong behavior.
The state of the app is contained in an InheritedWidget that is called before all the others. For example, in this InheritedWidget there is a value that must always be visible at the top of the app (in the AppBar). The problem is that if at runtime this value is changed in the InheritedWidget, the view shows the previous value (as if it wasn't updated), but if I do Navigator.push() to a new page, the AppBar shows the correct value (i.e. the updated one). If I pop to the previous page, the old value reappears in the AppBar. If I put the app in the background and bring it back to the foreground, the correct value finally appears.
It seems that the view does not update even if the value changes in the InheritedWidget. I specify that before being displayed, this value is extracted directly from the InheritedWidget using context.dependOnInheritedWidgetOfExactType<InheritedWidgetName>(). I also specify that "updateShouldNotify" is set this way:
#override
bool updateShouldNotify(Session oldWidget) {
return true;
}
I wanted to ask if anyone knows what might be causing this problem.
Thanks in advance.

One page, multiple contexts ? Is that possible?

Here is my problem: I have an app that has 2 list view.builders. You can imagine the scenario.
within the Stateful widget, we have:
Widget build(ct)
{
and this returns a column widget that has TWO list views.
The problem I have is that one list view changes (or should change) the items in another list view.
So what are my options? To create two Widget build(ct1) and Widget build(ct2)??
Do we do that? How can I communicate changes to ct1?
Oh my goodness, I've tried a lot, even setState etc... nothing works.. Perhaps could someone tell me how I can invoke the page to be refreshed?? That would work.
I keep on finding the answers myself - but for anyone who has this issue, Flutter apparently has evolved... if you are using the latest version, I really believe that SetState() function should work for you.. you just need to use it in the right place.

Widgets inside Zend Framework - Where should they go?

I've been working with Zend Framework (using Doctrine as the ORM) for quite a while now, and done a few projects with it.
In a few upcoming projects I am requiring the need for widgets similar to how Wordpress does them. You have a post/page, which could look like:
Subscribe to my newsletter:
[subscribe/]
View my events
[events limit=5 sort=date/]
View this page's comments
[comments/]
Where say the subscribe widget would be replaced with Blog::subscribeWidget, and the events could be replaced with Events::eventsWidget, etc.
Now it has done my head in the past few weeks about how on earth do I do this??? I've come up with the following options:
I could place the widgets within controllers, and then call them like actions. Problem here is that code could be flying between controllers, and I have read this is expensive due to the amount of dispatches.
I could place the widgets as view helpers. So within the view I could have $this->renderPage($Page), which would then attend to all the widgets. Problem here is that what if the widgets need to do some business logic, like for example posting a new comment, that really shouldn't be within the view, should it?
The other option is to place widgets within the model? But then how on earth do they then render content for display?
Extra complications come when:
Say the comments widget would also handle posting, deleting of comments etc.
Say for the events listing, if I want to do an ajax request to the next page of events, using method #2 (view helpers) how would this work?
If I understand you correctly your widgets will need their own action controllers, which is where their logic for fetching data to be displayed, parsing form submissions, etc. should go. The difference between a widget and a page in this case is in how it's rendered, i.e. as an HTML fragment instead of as a whole page; you can use the Action View Helper to achieve this.
If your widget includes a form it should probably use AJAX to submit the form data back to the server, so that using the widget doesn't cause the user to accidentally navigate away from the page. You can inject the required JavaScript into the page you've included the widget into by using the Head Script Helper in your widget's view and/or action.
I left Richards reply, the problem, and further use cases cook in my brain for a while longer and ended up coming to a solution.
I will have the following view helpers and methods:
Content; with methods: render, renderWidgets, renderWidget, renderCommentsWidget (comments).
Event; with methods: renderEventsWidget (many events), renderEventWidget (one event)
Subscription; with methods: renderSubscribeWidget (subscription form).
I will have inside my configuration file:
app.widgets.comments.helper = content
app.widgets.subscribe.helper = subscription
app.widgets.events.helper = event
I will also have the following models:
Content for use for all pages.
Event for use for all events.
Subcriber for use for subscriptions to content
So inside my view I will do something like this:
echo $this->content()->render($this->Content)
Content::render() will then perform any content rendering and then perform rendering of the widgets by passing along to Content::renderWidgets(). Here we will use the configuration of app.widgets to link together the widget bbcode tag to it's appropriate view helper (using the naming convention 'render'.ucfirst($tag).'Widget'). So for example Content::renderCommentsWidget() would then proceed to render the comments.
Perhaps later on I will decide to have a Widget View Helper, and individual view helpers for each widget eg. ContentCommentsWidget View Helper. But for now that would just add additional unrequired complexity.
Now to answer the AJAX problem I mentioned. Say for the comments widget allowing for comments to be posted via ajax. It would simply have an appropriate method inside the Content Controller for it. So pretty much we also have a Event and Subscription controllers too - corresponding with the view helpers. Interaction between the view helper and controller will all be hard coded, there is no purpose for it to be soft coded.
I hope this helps someone else, and the current plan is to make the project where all this is used to be an open-source project. So maybe one day you can see it all in action.
Thanks.
Update:
You can find the source code of these ideas in action in the following repositories:
BalCMS - this is the actual CMS which contains the widgets in /application/modules/balcms/view/helpers and contains the configuration in /application/modules/config/application/balcms.yaml
BalPHP - this is the resource library which contains the widget view helper at /lib/Bal/View/Helper/Widget.php