Home > Back-end >  Unexpected null value in flutter build
Unexpected null value in flutter build

Time:07-14

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))
              ],
            ),
          ],
        ),
      ),
    );
  }
}
  • Related