StatelessWidget – рекомендуется для неизменяемых виджетов. Это такие виджеты которые не имеют внутреннего состояния, зависят только от конфигурационных параметров и от родительских виджетов.
Вот некоторые виджеты которые наследуются от StatelessWidget:
- Text()
- FlatButton()
- Container()
- и др.
Самая простая конструкция для создания виджета от суперкласса StatelessWidget:
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Text('my text');
}
}
StatelessWidget – нужен там где внутреннее состояние одно и оно сформировано параметрами и данными которые нам известны заранее.
StatefulWidget – рекомендуется для изменяемых виджетов, с изменяемым внутренним состоянием (State). Под изменяемым состоянием понимается изменение внутреннего состояния экземпляра класса в зависимости от какого-то события (по нажатию, времени и пр.) Для этого нужно создавать виджет котопый наследует StatefulWidget.
Вот некоторые виджеты, которые наследуются от StatefulWidget:
Самая простая конструкция для создания виджета от суперкласса StatefulWidget:
class MyWidget extends StatefulWidget {
@override
createState() => new MyWidgetState();
}
class MyWidgetState extends State<MyWidget> {
@override
initState() {
super.initState();
// ...
}
@override
Widget build(BuildContext context) {
return new Text('my text');
}
}
StatefulWidget – нужен когда внутренних состояний больше одного и они могут сменять друг друга.
Создатели Flutter рекомендуют использовать StatelessWidget везде, где можно обойтись без StatefulWidget. Это связано с тем что перестроение StatefulWidget стоит намного дороже (в плане потребления ресурсов и отрисовки). Так же рекомендуется сводить к минимуму дочерних виджетов в StatefulWidget. Оказывается это было ложным утверждением, разницы никакой нет.
Generics или обобщения позволяют добавить программе гибкости и уйти от жесткой привязки к определенным типам. Иногда возникает необходимость, определить функционал таким образом, чтобы он мог использовать данные любых типов. Вот простой пример который поможет вам понять что такое Generics:
void main (){
Person bob = Person("324", "Bob");
print(bob.id.runtimeType); // String
Person sam = Person(123, "Sam");
print(sam.id.runtimeType); // int
}
// T это Generic, если его не было,
//нам пришлось-бы использовать несколько классов для определения идентификатора пользователя,
//но в данном случае он Generic и мы можем передавать в него любой тип данных.
class Person<T>{
T id; // идентификатор пользователя
String name; // имя пользователя
Person(this.id, this.name);
}