I'm learning to use Inherited Widget so my widgets can easily share data, everything in the code seems to be fine but when I build(WEB), all it shows is a red screen saying "Unexpected null value", I'm not sure what's wrong because I'm new to null safety. Here is the code: I want to access a count variable from two widgets.
void main() {
runApp(const MaterialApp(home: RootWidget()));
}
class MyAncestor extends InheritedWidget {
final _MyAppState state;
const MyAncestor({Key? key, required Widget child, required this.state})
: super(key: key, child: child);
static MyAncestor of(BuildContext context) {
MyAncestor? result =
context.dependOnInheritedWidgetOfExactType<MyAncestor>();
assert(result != null, 'No Count found in context');
return result!;
}
@override
bool updateShouldNotify(MyAncestor oldWidget) {
return this.state.counterValue != oldWidget.state.counterValue;
}
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _counter = 0;
int get counterValue => _counter;
increment() {
setState(() => _counter );
}
decrement() {
setState(() => _counter--);
}
@override
Widget build(BuildContext context) {
return ListView(children: [
Text(
"This is the Stateful widget that houses the children and where the states can be accessed"),
MyAncestor(
child: RootWidget(),
state: this,
)
]);
}
}
class RootWidget extends StatelessWidget {
const RootWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final rootwidgetstate = MyAncestor.of(context).state;
return Scaffold(
body: Center(
child: Row(
children: [
Container(
child: Row(
children: [
Text('${rootwidgetstate.counterValue}'),
TextButton(
onPressed: rootwidgetstate.increment(),
child: Icon(Icons.add)),
TextButton(
onPressed: rootwidgetstate.decrement(),
child: Icon(Icons.add))
],
),
),
Container(
child: Row(
children: [
Text('${rootwidgetstate.counterValue}'),
TextButton(
onPressed: rootwidgetstate.increment(),
child: Icon(Icons.add)),
TextButton(
onPressed: rootwidgetstate.decrement(),
child: Icon(Icons.add))
],
)),
],
)),
);
}
}
CodePudding user response:
Try using this class:
class RootWidget extends StatelessWidget {
const RootWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final rootWidgetState = MyAncestor.of(context).state;
return Scaffold(
body: Center(
child: Row(
children: [
Row(
children: [
Text('${rootWidgetState.counterValue}'),
TextButton(
onPressed: () => rootWidgetState.increment(),
child: const Icon(Icons.add)),
TextButton(
onPressed: () => rootWidgetState.decrement(),
child: const Icon(Icons.add))
],
),
Row(
children: [
Text('${rootWidgetState.counterValue}'),
TextButton(
onPressed: () => rootWidgetState.increment(),
child: const Icon(Icons.add)),
TextButton(
onPressed: () => rootWidgetState.decrement(),
child: const Icon(Icons.add))
],
),
],
),
),
);
}
}
I also change a litle bit your example:
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: MyApp()));
}
class MyAncestor extends InheritedWidget {
final _MyAppState state;
const MyAncestor({Key? key, required Widget child, required this.state})
: super(key: key, child: child);
static MyAncestor of(BuildContext context) {
MyAncestor? result =
context.dependOnInheritedWidgetOfExactType<MyAncestor>();
//assert(result != null, 'No Count found in context');
return result!;
}
@override
bool updateShouldNotify(MyAncestor oldWidget) {
return state.counterValue != oldWidget.state.counterValue;
}
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _counter = 0;
int get counterValue => _counter;
increment() {
setState(() => _counter );
}
decrement() {
setState(() => _counter--);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter ListView"),
),
body: Scaffold(
body: MyAncestor(
state: this,
child: RootWidget(),
),
),
);
}
}
class RootWidget extends StatelessWidget {
const RootWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final rootWidgetState = MyAncestor.of(context).state;
return Scaffold(
body: Center(
child: Row(
children: [
Row(
children: [
Text('${rootWidgetState.counterValue}'),
TextButton(
onPressed: () => rootWidgetState.increment(),
child: const Icon(Icons.add)),
TextButton(
onPressed: () => rootWidgetState.decrement(),
child: const Icon(Icons.add))
],
),
Row(
children: [
Text('${rootWidgetState.counterValue}'),
TextButton(
onPressed: () => rootWidgetState.increment(),
child: const Icon(Icons.add)),
TextButton(
onPressed: () => rootWidgetState.decrement(),
child: const Icon(Icons.add))
],
),
],
),
),
);
}
}