Introduction: I have spent over an hour looking through StackOverflow seeking this answer; so, I have hesitantly decided to ask this question which I believe is unanswered. I hope that it am not repeating something that has been answered Ad nauseam.
I have been spending the last five weeks immersing myself in the study of the BLoC pattern (yes, I know that I'm about a year behind the curve). I have been watching several videos and reading a couple of books on the topic. I have learned that memory leaks occur if no dispose method is called. In many recent YouTube videos that I have watched, a stateful widget is recommended instead of a stateless widget, so that the dispose method can be used during the lifecycle of the app for preventing memory leaks.
Problem: what is the proper way to seat an Inherited Widget, via a Provide.of method, to gain the scope for the context of the stateful widget, so the dispose() method can be used during the lifecycle?
Relevant Code:
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();
}
}
Issue: I believe that the Provider.of method must be called inside of the _HomeState region of the code because this is where the context is available. However, by doing this, it removes it from the scope of the dispose method.
Question: What am I doing wrong regarding the availability of the scope of the dispose() method, is there an answer to this that I am not seeing?
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();
}
}