I would like to change application language every time that someone decide to change application language without restarting app. Everything is working using BLoC.
The problem I have I don't really understand one thing. If I pass to MaterialApp property title TodosLocalizations.of(context).translate("appTitle") it throws an error:
The method 'translate' was called on null.
Receiver: null
Tried calling: translate("appTitle")
But when I comment this line and pass the same thing to onGenerateTitle property using context everything is working without problem.
Can someone answer me why this happening or I might don't understand how to use this property (title) in this case.
When you call onGenerateTitle: (BuildContext context) => TodosLocalizations.of(context).title, it uses a new BuildContext, which already contains the LocalizedDelagate(), so it can be called with TodosLocalizations.of(context).
When you use it directly without onGenerateTitle within the same build method, you refer to an instance of context before the LocalizedDelagate() was created, so TodosLocalizations.of(context) doesn't return anything.
Related
I'm trying to get the update function in Flame game to work. I have a global variable called newInstructions that's a list that gets updated by a separate function. I want the update function to check when there's a new addition to the list and call a function (populateInfo) with that list as input. After looking at some of the documentation, I've come up with what I think would be the correct code, but it keeps returning this error:
The method 'query' isn't defined by the type 'List'
I think that part of this might come from my not fully understanding what the update/query methods do. With that, what does the query method do and what type should it be? How would I go about changing my code to fix that error?
Here is the update function that I wrote:
#override
void update(double dt){
final instructions = newInstructions.query<List>();
populateInfo(instructions);
}
With that, what does the query method do and what type should it be?
query is a Flame specific method that is used on the OrderedSet in each component where the children are stored, it is used to get children of a specific type. For example to get all Player components:
children.query<Player>();
How would I go about changing my code to fix that error?
Since you want to react to when something is added the newInstructions list you shouldn't do this check in update since this method runs at least 60 times per seconds, it's better to just react once when there is a new instruction added.
This can be done in a few different ways, you could for example put the newInstructions list in a class that you then have an add method on that both adds the instruction to a list contained within the class, and also calls populateInfo. You could also wrap the list in a ChangeNotifier like this.
I am trying to create a button within a for loop as the loop is connected to the main dart. Everything else is running fine but then I try to put in the raisebutton I seem to get these errors depending on the dart package I am using stating:
package:path/path.dart Context context Type: Context
The system path context.
This differs from a context created with new Context in that its Context.current is always the current working directory, rather than being set once when the context is created.
or
dart:js JsObject get context
The JavaScript global object, usually window.
I don't know if what I am doing is right or not, please help.
Here is part of my main dart where the for loop is suppose to go inside as the for loop is within a different dart file
I'm not sure why you are instantiating MyMenu so often or why you are passing MyMenu instance variables into a MyMenu instance method. You may want to look at a better way to structure your code.
But to answer your question, you have no access to the current BuildContext within your MyMenu class. Quickest remedy: pass the BuildContext as a parameter to buildMenuItemsList.
buildMenuItemsList(Section section, BuildContext context) { ... }
MyMenu().buildMenuItemsList(MyMenu().getSections()[index], context),
I have written and extension on Stream that allows me to call .watch(<some state>) and automatically keep the widget updated. It works really well, however, I call setState on passed states from the extension and because of this I get a warning saying The member 'setState' can only be used within instance members of subclasses of 'package:flutter/src/widgets/framework.dart'. My question is why is this not recommended/allowed?. To clarify, I get why I am getting the warning - I'm calling setState from another class - but why does Flutter "care" if I do this?
I have tried to find information on any reason for this, but I can only find the obvious workaround of adding a helper function, and no reason is given.
There could be two possible reasons why you are getting this error:
You are using a static or final keyword somewhere where you declare a state
You are unable to setState, because the extension is updating the state of the widget already
Let me know if you need any further help or I understood you wrong!
I use MultiProvider and then create all my models. Lazy loading is enabled and as such when I open my page widget the constructor of my model is called when I call Provider.of<>(context).
This initialize my model and the model gets fresh data.
I have the following issue however, when I pop the view(widget) and revisit the view(widget) later, Provider.of<>(context) is called again, but since the model was already initialized I get the previous data from the model (This is useful because I do use this to preserve state between certain screens).
I need my model to reinitialize since I need to refresh my data and reset the page values, and since the constructor is never called again, I don't get any of these.
No matter what I do, if I call the initialize method from initState() / didChangeDependencies() it always error since I'm changing the data while the widget is building.
I'm looking for something like the following:
MyChangeNotifier variable = MyChangeNotifier();
ChangeNotifierProvider.value(
value: variable,
child: child()
)
To reinitialize my class, but from what I read this is bad and don't know where to call it.
I have no idea how to proceed and any help would be appreciated.
So I found what I was looking for in the Provider actual documentation here.
The key is to call your code that would update the UI or trigger a rebuild inside a Future.microTask(). This will only then trigger the rebuild once the future completes and not trigger the rebuild while the widget tree is still building.
#override
initState() {
super.initState();
Future.microtask(() =>
context.read<MyNotifier>(context).getMyData(); // Or in my situation initialize the page.
);
}
I have an issue with the provider pattern, I have a solution to my problem i just wanted to check its a good method and if there a better alternates.
I am trying to update the text controllers text when they first load the widget to have the value stored in my provider state. Originally, I just created the text controller in the init and just loaded the state in the build method and set the controllers text.
This was working until i wanted to have some validation of the content that would prevent certain things being passed into the state ( for example preventing empty strings).
textController.addListener(() {
if( RULE ABOUT WHETHER TO SET STATE BASED ON TEXT){
state.textField = textController.text;
}
});
The problem arose here, as they user would delete their word and this would fail the rule. The rebuild would occur (as they had pressed a key) and the text.controller would then rebuild to what was in the state (a single letter as it failed the rule). Effectively this prevented them from deleting, which is something i want them to be able to do but for this not to update the state.
I found this library https://pub.dev/packages/after_layout which allows a method to be overridden which is called once immediately after the build.
My solution uses this by creating the text controller in the initstate.
Assigning it to the TextField in the build.
Then creating a local field that would maintain the textField widget string content.
Then in the new afterbuild method i would assign whats on the state to the variable and update the text controllers text to have this value.
Then in the text.controllers text changed listener I used my rule to only update this state if it met the rule. Therefore if they deleted content they shouldn't be able to and closed/reopened the widget the state would rebuild to still have a valid value.
Is using this library a good solution to this or is there a better technique?
---------------- EDIT
Sorry for my wordy first part. I think my main question is just how am i meant to init Controllers if the data i need has to come from the state in the build.
For example.
// This must go in the build as it requires state
myTabsController = TabController(length: myState.list.length, vsync: this);
I'm initialisng the controller every time it builds now... How am i meant to put this in the init but still access the state variables.
(I've tried using the afterFirstLayout() callback from the AfterLayoutMixin but that just causes more problems.
Feel free to ask me to clarify more.
Thanks for your help.