Mahmoud Al-Haroon
Mahmoud Al-Haroon

Reputation: 2449

how to refresh Old screen when update second using inherited widget in flutter

I have created a simple app using InheritedWidget, just a counter app...

I have just four files:

  1. main.dart.
  2. CommonScreenProvider.dart.
  3. first_screen.dart.
  4. second_screen.dart.

the problem here when I am trying to use the counter function in in the second_screen and go back to the first_screen I can not find any updates till I use the counter but while I use counter in first screen I found the updated value in the second screen without problem, I think there's missing a refresh function or something?

Here's the code implementation...

CommonScreenProvider

import 'package:flutter/material.dart';

class CommonScreenProvider extends InheritedWidget {
  num counter = 0;
  Widget child;
  CommonScreenProvider({@required this.child});

  @override
  bool updateShouldNotify(covariant CommonScreenProvider oldWidget) {
    return oldWidget.counter != counter;
  }

  static CommonScreenProvider of(BuildContext ctx) =>
      ctx.dependOnInheritedWidgetOfExactType();
}

first_screen

import 'package:flutter/material.dart';
import 'package:statemanagementtest/second_screen.dart';

import 'commom_screen_provider.dart';

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext ctx) {
    var provider = CommonScreenProvider.of(ctx);
    return Scaffold(
      appBar: AppBar(
        actions: [
          IconButton(
            icon: Icon(Icons.send_to_mobile),
            onPressed: () {
              Navigator.of(ctx).push(
                MaterialPageRoute(
                  builder: (ctx) => SecondScreen(),
                ),
              );
            },
          ),
        ],
        title: Text('My Counter App'),
      ),
      body: Center(
        child: StatefulBuilder(builder: (ctx, StateSetter setState) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              IconButton(
                icon: Icon(Icons.remove),
                iconSize: 50,
                onPressed: () {
                  setState(() {
                    provider.counter--;
                  });
                },
              ),
              Text(
                '${provider.counter}',
                style: Theme.of(ctx).textTheme.display1,
              ),
              IconButton(
                icon: Icon(Icons.add),
                iconSize: 50,
                onPressed: () {
                  setState(() {
                    provider.counter++;
                  });
                },
              ),
            ],
          );
        }),
      ),
    );
  }
}

second_screen

import 'package:flutter/material.dart';

import 'commom_screen_provider.dart';

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext ctx) {
    var pSecond = CommonScreenProvider.of(ctx);
    return Scaffold(
      appBar: AppBar(
        title: Text('My Counter App'),
      ),
      body: Center(
        child: StatefulBuilder(builder: (ctx, StateSetter setState) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              IconButton(
                icon: Icon(Icons.remove),
                iconSize: 50,
                onPressed: () {
                  setState(() {
                    pSecond.counter--;
                  });
                },
              ),
              Text(
                '${pSecond.counter}',
                style: Theme.of(ctx).textTheme.display1,
              ),
              IconButton(
                icon: Icon(Icons.add),
                iconSize: 50,
                onPressed: () {
                  setState(() {
                    pSecond.counter++;
                  });
                },
              ),
            ],
          );
        }),
      ),
    );
  }
}

main.dart

import 'package:flutter/material.dart';
import 'package:statemanagementtest/commom_screen_provider.dart';
import 'package:statemanagementtest/first_screen.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext ctx) {
    return CommonScreenProvider(
      child: MaterialApp(
        home: FirstScreen(),
      ),
    );
  }
}

Upvotes: 0

Views: 502

Answers (1)

chunhunghan
chunhunghan

Reputation: 54367

You can copy paste run full code below
Quick fix is move StatefulBuilder up and await Navigator.of(ctx).push then call setState
code snippet

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext ctx) {
    var provider = CommonScreenProvider.of(ctx);
    return StatefulBuilder(builder: (ctx, StateSetter setState) {
      return Scaffold(
        appBar: AppBar(
          actions: [
            IconButton(
              icon: Icon(Icons.send_to_mobile),
              onPressed: () async {
                await Navigator.of(ctx).push(
                  MaterialPageRoute(
                    builder: (ctx) => SecondScreen(),
                  ),
                );

                setState(() {});

working demo

enter image description here

full code

import 'package:flutter/material.dart';

class CommonScreenProvider extends InheritedWidget {
  num counter = 0;
  Widget child;
  CommonScreenProvider({@required this.child});

  @override
  bool updateShouldNotify(covariant CommonScreenProvider oldWidget) {
    return oldWidget.counter != counter;
  }

  static CommonScreenProvider of(BuildContext ctx) =>
      ctx.dependOnInheritedWidgetOfExactType();
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext ctx) {
    var provider = CommonScreenProvider.of(ctx);
    return StatefulBuilder(builder: (ctx, StateSetter setState) {
      return Scaffold(
        appBar: AppBar(
          actions: [
            IconButton(
              icon: Icon(Icons.send_to_mobile),
              onPressed: () async {
                await Navigator.of(ctx).push(
                  MaterialPageRoute(
                    builder: (ctx) => SecondScreen(),
                  ),
                );

                setState(() {});
              },
            ),
          ],
          title: Text('My Counter App'),
        ),
        body: Center(
            child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            IconButton(
              icon: Icon(Icons.remove),
              iconSize: 50,
              onPressed: () {
                setState(() {
                  provider.counter--;
                });
              },
            ),
            Text(
              '${provider.counter}',
              style: Theme.of(ctx).textTheme.display1,
            ),
            IconButton(
              icon: Icon(Icons.add),
              iconSize: 50,
              onPressed: () {
                setState(() {
                  provider.counter++;
                });
              },
            ),
          ],
        )),
      );
    });
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext ctx) {
    var pSecond = CommonScreenProvider.of(ctx);
    return Scaffold(
      appBar: AppBar(
        title: Text('My Counter App'),
      ),
      body: Center(
        child: StatefulBuilder(builder: (ctx, StateSetter setState) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              IconButton(
                icon: Icon(Icons.remove),
                iconSize: 50,
                onPressed: () {
                  setState(() {
                    pSecond.counter--;
                  });
                },
              ),
              Text(
                '${pSecond.counter}',
                style: Theme.of(ctx).textTheme.display1,
              ),
              IconButton(
                icon: Icon(Icons.add),
                iconSize: 50,
                onPressed: () {
                  setState(() {
                    pSecond.counter++;
                  });
                },
              ),
            ],
          );
        }),
      ),
    );
  }
}

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext ctx) {
    return CommonScreenProvider(
      child: MaterialApp(
        home: FirstScreen(),
      ),
    );
  }
}

Upvotes: 1

Related Questions