A bit of a Flutter newbie, I hope you can help with this question.
I have two widgets on the main screen of my app. the top widget is a Facebook banner ad widget, the bottom part of the screen is then taken up with a list that is populated from an web API call.
When I use the toolbar to refresh the data from the API, I am using SetState to rebuild the list etc.
However, the top widget, with the Facebook ad is also being rebuilt each time, which is not what I want.
I have seen lots of talk about Bloc Patterns etc. If sounds like a bit of overkill for what I want to do, is there an easier way to just update the list without updating the banner ad widget?
Thanks
I can think of two solutions:
move the list to a separate StatefulWidget. If setState() is now called in this widget, only the included widget will be rebuilt.
something in the direction:
class _MyWidgetState extends State<MyWidget> {
Widget _facebookBanner;
#override
void initState() {
_facebookBanner = ...;
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(children: <Widget>[
_facebookBanner,
ListView(...),
]);
}
}
you should add a key property to your widget, it allows you to keep a specific widget from rebuilding when changing state.
You can define the Facebook banner as const, it won't be rebuilt when declared like that
This is an example of how to use const keyword
child: const Text('This is just an example of a const widget');
Const constructors are a great optimization for stuff that you know that won't change.
Related
Both the initState() method and didChangeDependencies() are executed before the build() method of a state object, so why is the context not available inside initState() but available inside didChangeDependencies()?
According to the official docs, didChangeDependencies() is called whenever the dependency of the State object changes. What does dependency mean here, and when does it change? (I am a beginner, so please use layman's term to explain this concept to me. I looked up other similar questions, but was not able to understand this.)
Unrelated to this topic, I understand that flutter creates elements and renderObjects for each widget it encounters in the widget tree and if that widget is a statefulWidget, then a state object is also created and a reference to that state object is held inside the element. My question is when are the element, renderObject and state object associated with a widget completely removed from their corresponding trees? Does this happen when the widget is permanently removed from the widget tree, or are they kept even after the widget is removed from the widget tree and some other widget is displayed in its place? For example, let's say that I have a floating action button on my homepage and on clicking that I'm pushing a namedPage onto the stack using the pushNamed method of the Navigator class and displaying a new page. Let's say that the new page is a StatefulWidget which has a state object associated with it, so when I go back to my home page again using the back button, that StatefulWidget is removed from the widget tree, right? Are the State object, element and renderObject associated with that widget destroyed immediately, or does flutter keep them around? If flutter does keep them around for some time, then how does it decide when to destroy those objects?
Firstly, you have to understand what is BuildContext that usually name as context.
buildContext is: the place in the widget tree in which this widget is placed.
All widgets have a bool this.mounted property. It is turned true
when the buildContext is assigned. It is an error to call setState
when a widget is unmounted.
why unsafe to use context in initState is because the widget is unmounted. means that the widget doesn't have place in the widget tree.
didChangeDependencies(): This method is called immediately after initState on the first time the widget is built.
its safe now because property mounted is true.
for the 3rd, you may know about deactivate() method. here
this is another answer for full explanation of flutter widget lifecylce :Life cycle in flutter
I'm quite new to flutter and I'm trying to figure out the best way to build my widgets in the aspect of good performance while I have three choices:
1- Stateful Wigdet.
2- Stateless Widget.
3- Widget function(){} with a StatefulBuilder if needed.
Thanks.
A StatefulWidget has State, which means that you can change stuff inside the widget without needing to destroy it and create a new version. They work slower than StatelessWidget but are better for checkboxes or screens which need to be frequently updated.
A StatelessWidget is locked, and you cannot change values once it is initiated. In order to change things inside the widget, you need to re-call the build function to build an updated version. They are quite fast but are best used for static screens.
Widget function(){} widgets are custom-made. Essentially, you can take any existing widget and modify it, adding childs and other widgets to it. However, the widget type normally inherits from a StatefulWidget or StatelessWidget. These can cover basically everything.
The core concept of StatelessWidget and StatefulWidget is confusing to me.
According to flutter documentary:
A widget is either stateful or stateless.
If a widget can change—when a user interacts with it, for example—it’s stateful.
A stateless widget never changes. Icon, IconButton, and Text are examples of stateless widgets. Stateless widgets subclass StatelessWidget.
so mainly if you have something on the screen that changes when user interacts with it, you should use stateful widget for it and otherwise, you should use stateless widget.
for example if you have a plus button on the screen and a a number on the screen which should be increased every time the user press it, you should use stateful widget to notify flutter that the text on the screen should be changed and rerendered.
for more information you can check here.
I started with the default Statfull Widget HomePage and a FAB.
The main widget in the page is a ListBuilder that is updated from a stream using Provider.
When an item on the list is clicked, I need to change the icon on the FAB.
All this works fine.
Now I wonder, If I would like to change the home page as a StatelessWidget. So I don't need to build the entire page just to change the icon on the FAB.
How can I update the Icon if I don't have setState() to rebuild the page?
the best answer should be use some sort of state management, but here's a quick and easy way to achieve your goal
create a function in your parent widget
Function callback(){
setState((){
//change Icon
});
}
Then pass it on to your stateless widget
CustomFabWidget(callback)
I want the button to display on top of the GraphQL provider widget, and still be functional as it is going to be used for routing. I want both to run simultaneously(or as close as possible so it doesn't ruin the UI when loading).
I've tried running both of the widgets at the top but they do not run as I would like them to.
void main() {
runApp(LoginPage());
runApp(Login());
class LoginPage extends StatelessWidget
class Login extends StatelessWidget
I thought the output would be the Login widget layered on top of LoginPage but it was just the Login widget expanded without the LoginPage widget running in the background.
From the runApp documentation:
Calling runApp again will detach the previous root widget from the screen and attach the given widget in its place.
And:
If you wish to align your widget to one side of the screen (e.g., the top), consider using the Align widget. If you wish to center your widget, you can also use the Center widget
So, as #Nae said in the comments, you can use Stack for that. Like:
Stack(
children: <Widget>[
LoginPage(),
Login(),
]
)