StatelessWidget

Последнее обновление: 01.02.2021

Как правило, при создании приложения новые виджеты обычно определяются как подклассы либо класса StatelessWidget, либо класса StatefulWidget. В чем разница между ними?

Виджеты бывают двух видов: stateful (имеют состояние) и stateless (не имеют состояния).

Виджеты, которые не имеют состояния, (stateless) в процессе работы приложения не изменяют своих свойств. Такие виджеты не имеют состояния. Они могут изменяться лишь посредством внешних событий, которые возникают на родительских виджетах-контейнерах. И класс StatelessWidget как раз представляет данный тип виджетов.

Виджеты, которые хранят состояние, (stateful) в процессе работы приложения могут изменять свои свойства динамически. Состояние хранится в виде объекта класса State. И класс StatefulWidget представляет виджеты, которые могут хранить состояние.

Вначале рассмотрим, как мы можем работать с классом StatelessWidget.

Этот класс подходит для создания виджетов, которые не хранят состояние. При создании своего подкласса необходимо переопределить метод build(). Этот метод используется для построения интерфейса и вызывается обычно в трех ситуациях:

  • когда виджет в первый раз добавляется в дерево виджетов, которое описывает пользовательский интерфейс

  • когда контейнер, в котором расположен подкласс StatelessWidget, меняет конфигурацию подкласса StatelessWidget

  • когда меняется объект InheritedWidget, от которого зависит подкласс StatelessWidget

Если контейнер часто меняет конфигурацию вложенного StatelessWidget, соответственно метод build() будет вызываться также часто. И в этой ситуации возможно потребуется оптимизировать вызов этого метода. Для этого можно минимизировать количество виджетов, которые создаются в методе build(). Еще одна техника в использовании оператора const при определении виджетов, насколько это возможно, а также в определении для виджетов константного конструктора.

Определение простейшего подкласса StatelessWidget:

class MyStatelessWidget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    
    return Container(
      color: Colors.white,
    );
  }
}

В качестве параметра в метод build() передается объект BuildContext, который содержит информацию о контексте виджета.

Метод build() должен возвращать другой виджет. В данном случае он возвращает виджет Container.

Как использовать свой виджет? Создадим и используем простейший виджет:

import 'package:flutter/material.dart';

void main() {
  runApp(MyStatelessWidget());
}

class MyStatelessWidget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {

    return Container(
      color: Colors.white,
      padding: EdgeInsets.only(top:40),
      child: const Text(
          "Hello Flutter from METANIT.COM",
          style: TextStyle(fontSize: 22, color: Colors.lightBlue),
          textAlign: TextAlign.center,
          textDirection: TextDirection.ltr,
      ),
    );
  }
}
Виджет StatelessWidget в Flutter и Dart

В данном случае кастомный виджет содержит более сложную структуру - он содержит Container, который, в свою очередь, содержит виджет Text.

В методе runApp() используем этот виджет в качестве главного контейнера для нашего приложения:

runApp(MyStatelessWidget());

В данном случае наш кастомный виджет выполняет роль контейнера, который содержит все остальные виджеты. Однако он может использоваться и в качестве вложенного элемента. Например:

import 'package:flutter/material.dart';

void main() {
  runApp(Container(
    color: Colors.white,
    padding: EdgeInsets.only(top:40),
    child: const MyStatelessWidget(),
  ));
}

class MyStatelessWidget extends StatelessWidget{
  const MyStatelessWidget({ Key key }) : super(key: key);
  @override
  Widget build(BuildContext context) {

    return Text(
          "Hello Flutter!",
          style: TextStyle(fontSize: 22, color: Colors.lightBlue),
          textAlign: TextAlign.center,
          textDirection: TextDirection.ltr,
    );
  }
}
конструктор const виджета StatelessWidget в Flutter и Dart

В данном случае виджет MyStatelessWidget выступает в качестве вложенного по отношению к элементу Container. Стоит отметить, что здесь в виджете также определен константный конструктор. Его определение в принципе необязательно, это лишь позволяет при использовании виджета применить оператор const:

child: const MyStatelessWidget(),

В качестве параметра в конструктор передается параметр Key, который передается далее в конструктор базового класса StatelessWidget.

const MyStatelessWidget({ Key key }) : super(key: key);

При вызове виджета нам не надо в него передавать явным образом объект Key - этот объект передается системой.

Определение конструкторов и передача данных

Выше определенный конструктор фактически повторяет конструктор базового класса StatelessWidget. Однако мы можем определить и другие конструкторы при необходимости. Обычно конструкторы применяются для передачи в виджет извне некоторых данных. Например:

import 'package:flutter/material.dart';

void main() {
  runApp(Container(
    color: Colors.white,
    padding: EdgeInsets.only(top:40),
    child: const MyStatelessWidget(myText: "Flutter on metanit.com", myColor: Colors.redAccent),
  ));
}

class MyStatelessWidget extends StatelessWidget{
  final String myText;
  final Color myColor;
  const MyStatelessWidget({ Key key, this.myText, this.myColor }) : super(key: key);

  @override
  Widget build(BuildContext context) {

    return Text(
          myText,
          style: TextStyle(fontSize: 22, color: myColor),
          textAlign: TextAlign.center,
          textDirection: TextDirection.ltr,
    );
  }
}

В данном случае в конструктор MyStatelessWidget также передается извне цвет и текст, которые затем используются для вывода текста.

Передача параметров в виджет StatelessWidget в Flutter и Dart

Подобным образом мы можем задать и вложенные виджеты в подклассе StatelessWidget:

import 'package:flutter/material.dart';

void main() {
  runApp(Container(
    color: Colors.white,
    padding: EdgeInsets.only(top:25),
    child: const MyStatelessWidget(
      myColor: Colors.tealAccent,
      myChild: Text("Flutter на metanit.com",
        style: TextStyle(fontSize: 22, color: Colors.teal),
        textAlign: TextAlign.center,
        textDirection: TextDirection.ltr,),
    ),
  ));
}

class MyStatelessWidget extends StatelessWidget{

  final Widget myChild;
  final Color myColor;

  const MyStatelessWidget({ Key key, this.myChild, this.myColor = Colors.white70}) : super(key: key);

  @override
  Widget build(BuildContext context) {

    return Container(
      color: myColor,
      child: myChild
    );
  }
}

В данном случае виджет, который будет содержаться во вложенном элементе Container, передается через свойство myChild.

Child в виджете StatelessWidget в Flutter и Dart
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850