Stateful-виджеты исчезнут: Stateful Builder

Stateful-виджеты должны исчезнуть: Stateful Builder

Как и сказано в названии, вам не всегда нужен StatefulWidget.

При разработке приложений Flutter, в зависимости от виджета, метод build может быть огромным. И использование StatefulWidget означает перестроение всей иерархии виджетов при каждом вызове setState .

Есть и более изящный способ обработки изменений состояния — использование StatefulBuilder.

Если вы только начинаете разрабатывать на Flutter, обратите внимание на статью Создание первого приложения Flutter и продолжение.

Stateful Builder

StatefulBuilderэто виджет Flutter, позволяющий встраивать состояние прямо в метод build. Этот виджет использует метод StatefulWidgetBuilder. В нём два параметра, context и setState. Параметр context это параметр типа BuildContext. Но наиболее интересен параметр setState.

typedef StatefulWidgetBuilder = Widget Function(BuildContext context, StateSetter setState);

Посмотрев в исходники StatefulWidgetBuilder, мы увидим, что setState это StateSetter. StateSetter это обратный вызов к State.setState. При его вызове, метод перестраивает иерархию виджетов с учётом их изменений.

Как использовать Stateful Builder

StatefulBuilder лучше всего использовать когда у вас средняя/большая иерархия виджетов, но состояние меняется только у небольшой его части.

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: MyApp()));

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amberAccent,
      body: SafeArea(
        child: Center(
          child: PersonCard(),
        ),
      ),
    );
  }
}

class PersonCard extends StatelessWidget {
  int counter = 0;
  @override
  Widget build(BuildContext contex) {
    return Card(
      child: SizedBox(
        width: 300.0,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.all(18.0),
                  child: Text(
                    "Luke Skywalker",
                    style:
                        TextStyle(fontSize: 16.0, fontWeight: FontWeight.w700),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(18.0),
                  child: Text(
                    "Age:  23",
                    style:
                        TextStyle(fontSize: 16.0, fontWeight: FontWeight.w700),
                  ),
                ),
              ],
            ),
            SizedBox(height: 12.0),
            Center(
              child: Container(
                height: 130.0,
                width: 130.0,
                child: Image.asset("assets/skywalker.png"),
              ),
            ),
            SizedBox(height: 12.0),
            StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    IconButton(
                      icon: Icon(Icons.skip_previous),
                      onPressed: () {
                        setState(() {
                          counter--;
                        });
                      },
                    ),
                    Text(
                      "$counter",
                      style: Theme.of(context).textTheme.body2,
                    ),
                    IconButton(
                      icon: Icon(Icons.skip_next),
                      onPressed: () {
                        setState(() {
                          counter++;
                        });
                      },
                    ),
                  ],
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

Здесь показана работа StatefulBuilder с виджетом Card. Вместо того, чтобы сделать всю Card stateful, мы используем StatefulBuilder для построения только той секции дерева виджетов, в которой есть state . В этом случае мы используем его только для построения Row с кнопками и текстом. В результате, при срабатывании onPressed и вызове setState, будут перестроены только Row и его потомки.

Stateful-виджеты должны исчезнуть: Stateful Builder

Если бы мы сделали виджет полностью stateful, то вместо перестроения только Row, это затронуло бы весь Card.

Stateful-виджеты должны исчезнуть: Stateful Builder
Рис. 1: Штриховкой показана область перестроения

Видео законченного приложения:

Перевод статьи «Stateful Widgets be gone: Stateful Builder»

Подписывайтесь на новости Flutter! https://t.me/flutterdaily

Stateful-виджеты должны исчезнуть: Stateful Builder

Разработчик: java, kotlin, c#, javascript, dart, 1C, python, php.

Пишите: @ighar. Buy me a coffee, please :).

Leave a Comment

Чтобы не пропустить новые статьи, оставь свой Email

Поздравляем вы подписаны на новости ТехноДжем!

TВо время отправки данных произошла ошибка. Попробуйте ещё раз

Оставляя свою почту