Don't understand InheritedWidget

32 Views Asked by At

I just started writing my own UI package for Flutter. Currently I am working on the theme. I want to have a widget like MaterialApp where I can add my theme and later other customizations and then I want to use my theme inside the widget tree by just writing: MiroTheme.of(context).primaryColor for example. Here is the code for my MiroApp widget:

import 'package:miro/miro.dart';
import 'package:flutter/widgets.dart';

class MiroApp extends StatelessWidget {
  final MiroThemeData theme;
  final Widget home;

  const MiroApp({
    super.key,
    required this.theme,
    required this.home,
  });

  @override
  Widget build(BuildContext context) {
    return MiroTheme(
      data: theme,
      child: home,
    );
  }
}

The code for my MiroTheme InheritedWidget looks like this:

import 'package:flutter/widgets.dart';
import 'package:miro/miro.dart';

class MiroTheme extends InheritedWidget {
  final MiroThemeData data;

  const MiroTheme({
    super.key,
    required this.data,
    required super.child,
  });

  static MiroThemeData of(BuildContext context) {
    final miroTheme = context.dependOnInheritedWidgetOfExactType<MiroTheme>();

    if (miroTheme == null) {
      throw Exception('No MiroTheme found in context');
    }

    return miroTheme.data;
  }

  @override
  bool updateShouldNotify(MiroTheme oldWidget) {
    return true;
  }
}

My problem is that when I want to use my package, I get the error that no miro theme is found in context. The code looks like this:

import 'package:flutter/widgets.dart';
import 'package:miro/miro.dart';

void main() {
  runApp(
    const MyApp(),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MiroApp(
      theme: const MiroThemeData(
        primaryColor: Color.fromARGB(255, 204, 98, 32),
      ),
      home: Container(
        color: MiroTheme.of(context).primaryColor,
      ),
    );
  }
}

I found that I could fix this by creating a custom widget for my Container home widget. The modified code is as follows:

import 'package:flutter/widgets.dart';
import 'package:miro/miro.dart';

void main() {
  runApp(
    const MyApp(),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MiroApp(
      theme: MiroThemeData(
        primaryColor: Color.fromARGB(255, 204, 98, 32),
      ),
      home: MyHomeWidget(),
    );
  }
}

class MyHomeWidget extends StatelessWidget {
  const MyHomeWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: MiroTheme.of(context).primaryColor,
    );
  }
}

This code works as I expected. But why do I have to create a separate widget for my home widget and cannot use the earlier solution? Is there a way to fix this or is there a bug in my code? Sorry if this post is too long.

0

There are 0 best solutions below