Provider: simply Exposing and Reading value

Created on 22 Sep 2019  路  2Comments  路  Source: rrousselGit/provider

You suppose i have this class data

class ApplicationColors {
  Color appForegroundColor;
  Color appBackgroundColor;
  Color appMainTextColor;
}

and this class as Notifier

class ApplicationColorManager extends ChangeNotifier{
  ApplicationColors colors;

  void setColors(ApplicationColors colors){
    this.colors = colors;
    notifyListeners();
  }
}

with define into MultiProvider:

ChangeNotifierProvider<ApplicationColorManager>.value(value: ApplicationColorManager()),

now how can i read this value as colors inside application with this code:

Provider<ApplicationColorManager>.value(
  value: 'Hello World', // <------ how can i read?
  child: MaterialApp(
    home: Home(),
  )
)

Most helpful comment

As far as I understand you're trying to make a responsive color customization manager for your whole app. In that case you can simply use a consumer to wrap your whole app to listen the changes in that notifier.

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider(
            builder: (_) => ApplicationColorManager(),
          )
        ],
        child: Consumer<ApplicationColorManager>(
          builder: (context, colorManager, _) {
            return MaterialApp(
              home: Home(),
              theme: ThemeData(
                  primaryColor: colorManager.colors.appForegroundColor),
                  // ... other global color customizations.
            );
          },
        ));
  }
}

And if you need to access your ApplicationColorManager in any other widget. You can simply trace your ApplicationColorManager on the widget tree using context like this:

ApplicationColorManager applicationColorManager =  Provider.of<ApplicationColorManager>(context);

My test application was like that:

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

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

class ApplicationColors {
  Color appForegroundColor;
  Color appBackgroundColor;
  Color appMainTextColor;
  ApplicationColors(
      {this.appForegroundColor,
      this.appMainTextColor,
      this.appBackgroundColor});
}

ApplicationColors defaultApplicationColors = ApplicationColors(
    appBackgroundColor: Colors.green,
    appForegroundColor: Colors.blue,
    appMainTextColor: Colors.pink);

class ApplicationColorManager extends ChangeNotifier {
  ApplicationColors colors = defaultApplicationColors;

  void setColors(ApplicationColors colors) {
    this.colors = colors;
    notifyListeners();
  }
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider(
            builder: (_) => ApplicationColorManager(),
          )
        ],
        child: Consumer<ApplicationColorManager>(
          builder: (context, colorManager, _) {
            return MaterialApp(
              home: Home(),
              theme: ThemeData(
                  primaryColor: colorManager.colors.appForegroundColor),
            );
          },
        ));
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ApplicationColorManager applicationColorManager =
        Provider.of<ApplicationColorManager>(context);
    return Scaffold(
        backgroundColor: applicationColorManager.colors.appBackgroundColor,
        appBar: AppBar(),
        body: Center(
          child: RaisedButton(
              onPressed: () {
                ApplicationColors alternativeColors = ApplicationColors(
                    appMainTextColor: Colors.red,
                    appForegroundColor: Colors.teal,
                    appBackgroundColor: Colors.orange);
                applicationColorManager.setColors(alternativeColors);
              },
              child: Text('Change App color')),
        ));
  }
}

Another approach would be using another consumer in the widgets.

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

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

class ApplicationColors {
  Color appForegroundColor;
  Color appBackgroundColor;
  Color appMainTextColor;
  ApplicationColors(
      {this.appForegroundColor,
      this.appMainTextColor,
      this.appBackgroundColor});
}

ApplicationColors defaultApplicationColors = ApplicationColors(
    appBackgroundColor: Colors.green,
    appForegroundColor: Colors.blue,
    appMainTextColor: Colors.pink);

class ApplicationColorManager extends ChangeNotifier {
  ApplicationColors colors = defaultApplicationColors;

  void setColors(ApplicationColors colors) {
    this.colors = colors;
    notifyListeners();
  }
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider(
            builder: (_) => ApplicationColorManager(),
          )
        ],
        child: Consumer<ApplicationColorManager>(
          builder: (context, colorManager, _) {
            return MaterialApp(
              home: Home(),
              theme: ThemeData(
                  primaryColor: colorManager.colors.appForegroundColor),
            );
          },
        ));
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<ApplicationColorManager>(
        builder: (context, colorManager, _) {
      return Scaffold(
          backgroundColor: colorManager.colors.appBackgroundColor,
          appBar: AppBar(),
          body: Center(
            child: RaisedButton(
                onPressed: () {
                  ApplicationColors alternativeColors = ApplicationColors(
                      appMainTextColor: Colors.red,
                      appForegroundColor: Colors.teal,
                      appBackgroundColor: Colors.orange);
                  colorManager.setColors(alternativeColors);
                },
                child: Text('Change App color')),
          ));
    });
  }
}

I hope this helps.

All 2 comments

As far as I understand you're trying to make a responsive color customization manager for your whole app. In that case you can simply use a consumer to wrap your whole app to listen the changes in that notifier.

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider(
            builder: (_) => ApplicationColorManager(),
          )
        ],
        child: Consumer<ApplicationColorManager>(
          builder: (context, colorManager, _) {
            return MaterialApp(
              home: Home(),
              theme: ThemeData(
                  primaryColor: colorManager.colors.appForegroundColor),
                  // ... other global color customizations.
            );
          },
        ));
  }
}

And if you need to access your ApplicationColorManager in any other widget. You can simply trace your ApplicationColorManager on the widget tree using context like this:

ApplicationColorManager applicationColorManager =  Provider.of<ApplicationColorManager>(context);

My test application was like that:

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

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

class ApplicationColors {
  Color appForegroundColor;
  Color appBackgroundColor;
  Color appMainTextColor;
  ApplicationColors(
      {this.appForegroundColor,
      this.appMainTextColor,
      this.appBackgroundColor});
}

ApplicationColors defaultApplicationColors = ApplicationColors(
    appBackgroundColor: Colors.green,
    appForegroundColor: Colors.blue,
    appMainTextColor: Colors.pink);

class ApplicationColorManager extends ChangeNotifier {
  ApplicationColors colors = defaultApplicationColors;

  void setColors(ApplicationColors colors) {
    this.colors = colors;
    notifyListeners();
  }
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider(
            builder: (_) => ApplicationColorManager(),
          )
        ],
        child: Consumer<ApplicationColorManager>(
          builder: (context, colorManager, _) {
            return MaterialApp(
              home: Home(),
              theme: ThemeData(
                  primaryColor: colorManager.colors.appForegroundColor),
            );
          },
        ));
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ApplicationColorManager applicationColorManager =
        Provider.of<ApplicationColorManager>(context);
    return Scaffold(
        backgroundColor: applicationColorManager.colors.appBackgroundColor,
        appBar: AppBar(),
        body: Center(
          child: RaisedButton(
              onPressed: () {
                ApplicationColors alternativeColors = ApplicationColors(
                    appMainTextColor: Colors.red,
                    appForegroundColor: Colors.teal,
                    appBackgroundColor: Colors.orange);
                applicationColorManager.setColors(alternativeColors);
              },
              child: Text('Change App color')),
        ));
  }
}

Another approach would be using another consumer in the widgets.

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

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

class ApplicationColors {
  Color appForegroundColor;
  Color appBackgroundColor;
  Color appMainTextColor;
  ApplicationColors(
      {this.appForegroundColor,
      this.appMainTextColor,
      this.appBackgroundColor});
}

ApplicationColors defaultApplicationColors = ApplicationColors(
    appBackgroundColor: Colors.green,
    appForegroundColor: Colors.blue,
    appMainTextColor: Colors.pink);

class ApplicationColorManager extends ChangeNotifier {
  ApplicationColors colors = defaultApplicationColors;

  void setColors(ApplicationColors colors) {
    this.colors = colors;
    notifyListeners();
  }
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider(
            builder: (_) => ApplicationColorManager(),
          )
        ],
        child: Consumer<ApplicationColorManager>(
          builder: (context, colorManager, _) {
            return MaterialApp(
              home: Home(),
              theme: ThemeData(
                  primaryColor: colorManager.colors.appForegroundColor),
            );
          },
        ));
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<ApplicationColorManager>(
        builder: (context, colorManager, _) {
      return Scaffold(
          backgroundColor: colorManager.colors.appBackgroundColor,
          appBar: AppBar(),
          body: Center(
            child: RaisedButton(
                onPressed: () {
                  ApplicationColors alternativeColors = ApplicationColors(
                      appMainTextColor: Colors.red,
                      appForegroundColor: Colors.teal,
                      appBackgroundColor: Colors.orange);
                  colorManager.setColors(alternativeColors);
                },
                child: Text('Change App color')),
          ));
    });
  }
}

I hope this helps.

@anotherglitchinthematrix thanks a lot. :heart: :heart: :heart:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jihongboo picture jihongboo  路  4Comments

rrousselGit picture rrousselGit  路  3Comments

guopeng1994 picture guopeng1994  路  4Comments

dikir picture dikir  路  5Comments

ykaito21 picture ykaito21  路  3Comments