Okay so I'm trying to learn Dart by following flutter tutorials.
In the example below, right after the object is declared, an instance of itself is "created" (or at least I think so) and I don't understand why.
class CounterDisplay extends StatelessWidget {
CounterDisplay({this.count}); // What does this line do ?
final int count;
#override
Widget build(BuildContext context) {
return Text('Count: $count');
}
}
This code is from the tutorial found on this page:
https://flutter.dev/docs/development/ui/widgets-intro#changing-widgets-in-response-to-input
The line in question is this one :
CounterDisplay({this.count});
Could someone explain to me what does this line do and why it's here?
This doesn't create an instance of the object.
It is instead what we call a "constructor". Such syntax allows specifying custom parameters that need to be passed when creating the object.
See the dart documentation on constructors for more informations.
This make argument optional when create new object, or pass the variable name when creating object .
Related
I saw a code like below.
I understood formKey is defined as GlobalKey type, and basically what <FormState> is? is this type as well?
I can declare field like final formKey GlobalKey; without any errors, but when I use if (_formKey.currentState.validate()) later, flutter says validate() are not defined as methods and finally I'm confusing gramatically what <FormState> is, especially way of using <>?
Or Is this Generics? but I'm still confusing that i just learned that
we can use Generics like as type placeholder. But this code shown below seems not like that.
I'm sorry that I'm really new about class or objective programing’, and do appreciate your kindness!
class TEST extends ConsumerWidget {
final formKey GlobalKey<FormState>;
//omit
The GlobalKey represents a key that is unique across your entire Flutter app. This is used to uniquely identify elements and provide access to objects that are associated to those elements. If the widget that has the global key associated, is stateful, the key also provide access to it's state.
If you check the GlobalKey class, you'll notice that it is declared as
abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {}
In your case, the FormState should be a sub-class of State, which it is. The FormState represents the state associated to your form. The FormState can be used to save, reset, and validate every FormField in your Form.
TLDR: T is a generic, specifically a class that should extend State<StatefulWidget> . In your case it is used as the return type of T? get currentState {} method and it represents the state of the associated form.
For your issue with the validate() method, you must actually write the validate() method and pass it to the validator: in the TextFormField(validate: HERE) widget. The method needs to return null if everything is ok, and the string with the validation error otherwise.
ex:
String? passwordValidator(String? value){
if(value == null || value.isEmpty){
return "Please fill this field";
}else {
return null;
}
} //This is a very dummy validator, do not use it in production.
This question already has answers here:
Difference between assigning the values in parameter list and initializer list
(2 answers)
Closed 1 year ago.
This code snippet
class SomeWidget extends StatelessWidget {
final String aString;
SomeWidget(this.aString);
compiles without error or warning. However, this code snippet
class SomeWidget extends StatelessWidget {
final String aString;
SomeWidget(String inputString) {
this.aString=inputString;
}
gives an error message that all final variables must be initialized and aString isn't, and how aString can't be used as a setter because it's final. Removing the final keyword eliminates the error messages.
I'm unclear what's going on here. I saw this and this SO item, but honestly I'm still struggling to understand. I think the problem, for me, stems from how I was taught my two code snippets are functionally identical.
When you declare a variable as final, this means that the state\value of this variable will not change during the life cycle of this widget.
Thus, when you declare:
final String aString;
You are telling the framework, that the value of aString, will not change, because it's final. However, when you use the setter, you are trying to do the exact opposite of what you just promised Flutter, and you are attempting to change what should be final = aka non-changeable.
I'm sorry if this sounds like an extremely foolish question but it's really been bugging me.
What is the "this." that I see? Whenever I see the documentation in flutter I see it used in things like the following in the documentation:
this.initialRoute,
this.onGenerateRoute,
this.onGenerateInitialRoutes,
this.onUnknownRoute,
this.navigatorObservers
I'll be more than happy to also read up any links or documentation regarding it.
The 'this' keyword refers to the current instance.
You only need to use this when there is a name conflict. Otherwise, Dart style omits the this.
class Car {
String engine;
void newEngine({String engine}) {
if (engine!= null) {
this.engine= engine;
}
}
}
So you can be consistent with the name of your parameters, either in the constructor or in some function in the class.
class Car {
String engine;
void updateEngine({String someWeirdName}) {
engine = someWeirdName;
}
}
If you don't have a name conflict, you don't need to use this.
In other languages like Python and Swift, the word 'self' will do the same thing as 'this'.
Basically, this keyword is used to denotes the current instance. Check out the below example.
void main() {
Person mike = Person(21);
print(mike.height);
}
class Person {
double height;
Person(double height) {
height = height;
}
}
When we run this dart code, it outputs null as the height. Because we have used height = height inside the Person constructor, but the code doesn't know which height is the class property.
Therefore, we can use this keyword to denotes the current instance and it will help the code to understand which height belongs to the class. So, we can use it as below and we will get the correct output.
void main() {
Person mike = Person(21);
print(mike.height);
}
class Person {
double height;
Person(double height) {
this.height = height;
}
}
Use of this keyword
The this keyword is used to point the current class object.
It can be used to refer to the present class variables.
We can instantiate or invoke the current class constructor using this keyword.
We can pass this keyword as a parameter in the constructor call.
We can pass this keyword as a parameter in the method call.
It removes the ambiguity or naming conflict in the constructor or method of our instance/object.
It can be used to return the current class instance.
I have a file fancy_button.dart for a custom Flutter widget FancyButton which is like:
class FancyButton extends StatefulWidget {
// ...
}
class _FancyButtonState extends State<FancyButton> {
// ...
}
// Declaration outside any class:
Map<_FancyButtonState, Color> _buttonColors = {};
final _random = Random();
int next(int min, int max) => min + _random.nextInt(max - min);
// ...
The application works just fine. Notice that I declare and use some variables outside any class. Now my question is: how is it even possible? Shouldn't everything be inside a class in Dart, like Java?
No, Dart supports variables and functions defined in global space. You can see this with the main() method which are declared outside any class.
Also, global variables (and static class variables) are lazy evaluated so the value are first defined when you are trying to use them. So your runtime are not going to slow down even if there are a bunch of global variables there are not used.
Are you coming from Java before touching Dart?
Basically, Dart is not single-class-single-file like how Java works. Yes, it does support Object Oriented Programming (in kinda different way). The behavior of constructor is different. There is no public, private, and protected keywords. Please just refer to the official docs.
Anyway, you don't need a complex public static void main(). The real entry point is main(). Unless you define that function, you won't be able to run a file in command line.
what does <RandomWords> mean? what is this grammar of Dart language?
class RandomWords extends StatefulWidget {
#override
State createState() {
return new RandomWordsState();
}
}
class RandomWordsState extends State<RandomWords>{
#override
Widget build(BuildContext context) {
return new Scaffold(
);
}
}
what does <RandomWords> mean? what is this grammar of Dart language?
You are specifying what State this state is about, in the same way that when you say something like:
List<String> a;
You are saying what this List is made of.
In another words, it means the State class is a Generic class.
In the documentation of List class you will see they actually refer to it as:
List<E> class.
So, whatever type you put in the List, all of the methods related that contains E (as a argument or as a return) will have the signature adjusted accordingly, i.e.:
last ↔ E
Returns the last element.
As you can see, the last method returns the same type that the List contains, which is the expected.
The use of this is mostly for type safety, so if you try to insert a number into a List< String>, the compiler will know and will detect the mistake.
Also, if you're the one developing a Generic class, it will help avoid code duplication, because you won't have to write a implementation for each possible List type in the world.
When defining your class, you can do something as follows (Example from dart Language Tour):
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
And, in their words:
In this code, T is the stand-in type. It’s a placeholder that you can think of as a type that a developer will define later.
Also, as a last tip, we can see on the documentation of the State class linked above that the generic type needs to be something that inherits from Stateful Widget, so you don't try to create a State< Int>, for example.
State < T extends StatefulWidget > class