Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing the theme rebuilds app with a custom navigator #18

Open
ahhmino opened this issue Jun 10, 2021 · 0 comments
Open

Changing the theme rebuilds app with a custom navigator #18

ahhmino opened this issue Jun 10, 2021 · 0 comments

Comments

@ahhmino
Copy link

ahhmino commented Jun 10, 2021

I'm using a custom navigator in my flutter app, and it seems to not play well with this plugin - whenever a theme is switched (using either nextTheme() or setThemeId(themeId), the app reverts to the initial route of the navigator and the initial state of that route. No state or route information is saved. Is there any workaround for this? Using flutter 2.2.1

I have two reproducible examples, one with a custom navigator and one without:

With custom navigator:

import 'package:flutter/material.dart';
import 'package:theme_provider/theme_provider.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ThemeProvider(
      child: ThemeConsumer(
        child: Builder(
          builder: (context) => MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeProvider.themeOf(context).data,
            home: MainNavigator(),
          ),
        ),
      ),
    );
  }
}

class MyCounterPage extends StatefulWidget {
  MyCounterPage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyCounterPageState createState() => _MyCounterPageState();
}

class _MyCounterPageState extends State<MyCounterPage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the FAB this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            TextButton(
                onPressed: () => Navigator.of(context).pushNamed("second"),
                child: Text("Tap here to go to the theme page"))
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class MainNavigator extends StatelessWidget {

  MainNavigator({Key? key}) : super(key: key);

  final GlobalKey<NavigatorState> navigatorKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        onWillPop: () async {
          return false;
        },
        child: Navigator(
          key: navigatorKey,
          initialRoute: "first",
          onGenerateRoute: (settings) {
            if(settings.name == "first") {
              return MaterialPageRoute(builder: (context) =>
                  MyCounterPage(title: 'Flutter Demo Home Page'),
                  settings: settings);
            }
            return MaterialPageRoute(builder: (context) =>
                MyThemePage(title: 'Flutter Demo Home Page'),
                settings: settings);
          },
        )
    );
  }
}

class MyThemePage extends StatefulWidget {
  MyThemePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyThemePageState createState() => _MyThemePageState();
}

class _MyThemePageState extends State<MyThemePage> {
  int _counter = 0;

  void _incrementCounter() {
    ThemeProvider.controllerOf(context).nextTheme();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Press the FAB to change the theme',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

Without custom navigator (using default routes in root material app):

import 'package:flutter/material.dart';
import 'package:theme_provider/theme_provider.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ThemeProvider(
      child: ThemeConsumer(
        child: Builder(
          builder: (context) => MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeProvider.themeOf(context).data,
            initialRoute: "first",
            onGenerateRoute: (settings) {
              if(settings.name == "first") {
                return MaterialPageRoute(builder: (context) =>
                    MyCounterPage(title: 'Flutter Demo Home Page'),
                    settings: settings);
              }
              return MaterialPageRoute(builder: (context) =>
                  MyThemePage(title: 'Flutter Demo Home Page'),
                  settings: settings);
            },
          ),
        ),
      ),
    );
  }
}

class MyCounterPage extends StatefulWidget {
  MyCounterPage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyCounterPageState createState() => _MyCounterPageState();
}

class _MyCounterPageState extends State<MyCounterPage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the FAB this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            TextButton(
                onPressed: () => Navigator.of(context).pushNamed("second"),
                child: Text("Tap here to go to the theme page"))
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class MyThemePage extends StatefulWidget {
  MyThemePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyThemePageState createState() => _MyThemePageState();
}

class _MyThemePageState extends State<MyThemePage> {
  int _counter = 0;

  void _incrementCounter() {
    ThemeProvider.controllerOf(context).nextTheme();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Press the FAB to change the theme',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
@ahhmino ahhmino changed the title Changing the theme rebuilds the entire widget tree Changing the theme rebuilds app with a custom navigator Jun 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant