Флаттер: Как правильно разместить метод Provider.of в StatefulWidget, чтобы Dispose () можно было использовать в моем коде? - PullRequest
0 голосов
/ 04 апреля 2020

Введение: Я потратил более часа, просматривая StackOverflow в поисках этого ответа; Итак, я нерешительно решил задать этот вопрос, который я считаю, без ответа. Я надеюсь, что это не повторяет то, на что был дан ответ Ad nauseam.

Я провел последние пять недель, погружаясь в изучение паттерна BLo C (да, я знаю, что я около года позади кривой). Я смотрел несколько видео и читал пару книг по теме c. Я узнал, что утечки памяти происходят, если не вызывается метод утилизации. Во многих недавних видео на YouTube, которые я смотрел, рекомендуется использовать виджет с отслеживанием состояния вместо виджета без сохранения состояния, чтобы метод утилизации можно было использовать в течение жизненного цикла приложения для предотвращения утечек памяти.

Проблема : как правильно разместить Inherited Widget, через метод Provide.of, чтобы получить область для контекста виджета с состоянием, поэтому метод dispose () можно использовать во время жизненный цикл?

Соответствующий код:

import 'package:flutter/material.dart';

import 'package:testingblock6/counter_provider.dart';
import 'counter_event.dart';
import 'model.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    final _bloc = Provider.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Testing Bloc 6'),
      ),
      body: Center(
          child: StreamBuilder<Model>(
        stream: _bloc.modelStream,
        initialData: Model(),
        builder: (BuildContext context, AsyncSnapshot<Model> snapshot) {
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                'Counter: ${snapshot.data.counter}',
                style: Theme.of(context).textTheme.display1,
              ),
              Text(
                'ThisGuy: ${snapshot.data.thisGuy}',
                style: Theme.of(context).textTheme.display1,
              ),
            ],
          );
        },
      )),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            onPressed: () => _bloc.counterEventSink.add(IncrementEvent()),
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
          SizedBox(width: 10),
          FloatingActionButton(
            onPressed: () => _bloc.counterEventSink.add(DecrementEvent()),
            tooltip: 'Decrement',
            child: Icon(Icons.remove),
          ),
          SizedBox(width: 10),
          FloatingActionButton(
            onPressed: () => _bloc.counterEventSink.add(ThisGuy()),
            tooltip: 'ThisGuy',
            child: Icon(Icons.golf_course),
          ),
        ],
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  @override
  void dispose() {
    super.dispose();
    // _bloc.dispose();
  }
}

Проблема: Я считаю, что метод Provider.of должен вызываться внутри _HomeState область кода, потому что это где контекст доступен. Однако, делая это, он удаляет его из области действия метода dispose.

Вопрос: Что я делаю неправильно в отношении доступности области действия метода dispose (), если есть ответ на этот вопрос, которого я не вижу?

1 Ответ

1 голос
/ 04 апреля 2020
import 'package:flutter/material.dart';

import 'counter_event.dart';
import 'counter_provider.dart';
import 'model.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  var _bloc;

  @override
  Widget build(BuildContext context) {
    _bloc = Provider.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Testing Bloc 6'),
      ),
      body: Center(
          child: StreamBuilder<Model>(
        stream: _bloc.modelStream,
        initialData: Model(),
        builder: (BuildContext context, AsyncSnapshot<Model> snapshot) {
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                'Counter: ${snapshot.data.counter}',
                style: Theme.of(context).textTheme.display1,
              ),
              Text(
                'ThisGuy: ${snapshot.data.thisGuy}',
                style: Theme.of(context).textTheme.display1,
              ),
            ],
          );
        },
      )),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            onPressed: () => _bloc.counterEventSink.add(IncrementEvent()),
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
          SizedBox(width: 10),
          FloatingActionButton(
            onPressed: () => _bloc.counterEventSink.add(DecrementEvent()),
            tooltip: 'Decrement',
            child: Icon(Icons.remove),
          ),
          SizedBox(width: 10),
          FloatingActionButton(
            onPressed: () => _bloc.counterEventSink.add(ThisGuy()),
            tooltip: 'ThisGuy',
            child: Icon(Icons.golf_course),
          ),
        ],
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  @override
  void dispose() {
    super.dispose();
    _bloc.dispose();
  }
}
...