{"id":13511402,"url":"https://github.com/google/flutter-provide","last_synced_at":"2025-03-30T20:33:12.377Z","repository":{"id":49188305,"uuid":"170767638","full_name":"google/flutter-provide","owner":"google","description":"A simple framework for state management in Flutter.","archived":true,"fork":false,"pushed_at":"2021-06-24T11:38:37.000Z","size":74,"stargazers_count":811,"open_issues_count":11,"forks_count":58,"subscribers_count":29,"default_branch":"master","last_synced_at":"2024-08-02T03:07:55.538Z","etag":null,"topics":["flutter","state-management"],"latest_commit_sha":null,"homepage":"https://pub.dartlang.org/packages/provide","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/google.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-14T22:36:19.000Z","updated_at":"2024-07-04T15:33:23.000Z","dependencies_parsed_at":"2022-08-30T21:40:39.205Z","dependency_job_id":null,"html_url":"https://github.com/google/flutter-provide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fflutter-provide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fflutter-provide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fflutter-provide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fflutter-provide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/google","download_url":"https://codeload.github.com/google/flutter-provide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222581265,"owners_count":17006322,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flutter","state-management"],"created_at":"2024-08-01T03:00:49.189Z","updated_at":"2024-11-01T13:30:56.565Z","avatar_url":"https://github.com/google.png","language":"Dart","readme":"**DEPRECATION NOTE:** \nAfter discussion in the Flutter community over the difference between this\npackage, `package:provider`, and `package:scoped_model` (all with a similar,\nInheritedWidget-based philosophy), we have decided to merge these efforts.\n\nThe community-initiated `provider` supersedes this package, `provide`. Get `provider`\n[here](https://pub.dev/packages/provider).\n\nTo be clear, this package will always be available at\n[pub.dev/packages/provide](https://pub.dev/packages/provide) — pub doesn't allow\npackages to \"disappear\". But the package likely won't be upgraded.\n\nSee [Issue #3](https://github.com/google/flutter-provide/issues/3) for the full\ndiscussion.\n\n\n---\n\nThis package contains classes to allow the passing of data down the widget tree.\nIt is designed as a replacement for `ScopedModel` that allows for more\nflexible handling of data types and data.\n\n## Key widgets and static methods\n\n  * `Provide\u003cT\u003e` - Widget used to obtain values from a `ProviderNode` higher up\n  in the widget tree and rebuild on change. The `Provide\u003cT\u003e` widget should\n  only be used with `Stream`s or `Listenable`s. Equivalent to\n  `ScopedModelDescendant` in `ScopedModel`.\n\n  * `Provide.value\u003cT\u003e` - Static method used to get a value from a `ProviderNode`\n  using the `BuildContext`. This will not rebuild on change. Similar to manually\n  writing a static `.of()` method for an `InheritedWidget`.\n\n  * `Provide.stream\u003cT\u003e` - Static method used to get a `Stream` from a\n  `ProviderNode`. Only works if either `T` is listenable, or if the\n  `Provider` comes from a `Stream`.\n\n  * `Provider\u003cT\u003e` - A class that returns a typed value on demand. Stored in\n  a `ProviderNode` to allow retrieval using `Provide`.\n\n  * `ProviderNode` - The equivalent of the `ScopedModel` widget. Contains\n  `Providers` which can be found as an `InheritedWidget`.\n\n## Usage\n\nThis is a simple example of a counter app:\n\n```dart\n\n/// A provide widget can rebuild on changes to any class that implements\n/// the listenable interface.\n///\n/// Here, we mixin ChangeNotifier so we don't need to manage listeners\n/// ourselves.\n///\n/// Extending ValueNotifier\u003cint\u003e would be another simple way to do this.\nclass Counter with ChangeNotifier {\n  int _value;\n\n  int get value =\u003e _value;\n\n  Counter(this._value);\n\n  void increment() {\n    _value++;\n    notifyListeners();\n  }\n}\n\n/// CounterApp which obtains a counter from the widget tree and uses it.\nclass CounterApp extends StatelessWidget {\n  // The widgets here get the value of Counter in three different\n  // ways.\n  //\n  // - Provide\u003cCounter\u003e creates a widget that rebuilds on change\n  // - Provide.value\u003cCounter\u003e obtains the value directly\n  // - Provide.stream\u003cCounter\u003e returns a stream\n  @override\n  Widget build(BuildContext context) {\n    // Gets the Counter from the nearest ProviderNode that contains a Counter.\n    // This does not cause this widget to rebuild when the counter changes.\n    final currentCounter = Provide.value\u003cCounter\u003e(context);\n\n    return Column(children: [\n      // Simplest way to retrieve the provided value.\n      //\n      // Each time the counter changes, this will get rebuilt. This widget\n      // requires the value to be a Listenable or a Stream. Otherwise\n      Provide\u003cCounter\u003e(\n        builder: (context, child, counter) =\u003e Text('${counter.value}'),\n      ),\n\n      // This widget gets the counter as a stream of changes.\n      // The stream is filtered so that this only rebuilds on even numbers.\n      StreamBuilder\u003cCounter\u003e(\n          initialData: currentCounter,\n          stream: Provide.stream\u003cCounter\u003e(context)\n              .where((counter) =\u003e counter.value % 2 == 0),\n          builder: (context, snapshot) =\u003e\n              Text('Last even value: ${snapshot.data.value}')),\n\n      // This button just needs to call a method on Counter. No need to rebuild\n      // it as the value of Counter changes. Therefore, we can use the value of\n      // `Provide.value\u003cCounter\u003e` from above.\n      FlatButton(child: Text('increment'), onPressed: currentCounter.increment),\n\n      Text('Another widget that does not depend on the Counter'),\n    ]);\n  }\n}\n\nvoid main() {\n    // The class that contains all the providers. This shouldn't change after\n    // being used.\n    //\n    // In this case, the Counter gets instantiated the first time someone uses\n    // it, and lives as a singleton after that.\n    final providers = Providers()\n      ..provide(Provider.function((context) =\u003e Counter(0)));\n\n    runApp(ProviderNode(\n      providers: providers,\n      child: CounterApp(),\n    ));\n}\n\n```\n\n## How it works\nSimilar to `ScopedModel`, this relies on `InheritedWidget`s in order to\npropagate data up and down the widget tree. However, unlike `ScopedModel`,\nrather than storing a single concrete type, a `ProviderNode` contains a map of\n`Type`s to `Provider`s. This means that a single node can contain any number of\nproviders, and that a provider of a type doesn't have to be of the exact\nconcrete type.\n\nSomewhere in the tree, there is a `ProviderNode`, which contains a set of\n`Provider`s. When a `Provide` widget is created, it searches up the widget tree\nfor a `ProviderNode` that contains a provider for its requested type. It then\nlistens for any changes to that requested type.\n\nThere are also static methods that operate on `BuildContext` that allow any\nwidget's build function to get data from `ProviderNode`s without listening to\nchanges directly.\n\n\n## Useful widgets to use with Provider\n* [ChangeNotifier](https://docs.flutter.io/flutter/foundation/ChangeNotifier-class.html)\n  — Easy way to implement Listenable. The equivalent of `Model` from\n  `ScopedModel`.\n\n* [ValueNotifier](https://docs.flutter.io/flutter/foundation/ValueNotifier-class.html)\n  — Wrapping your mutable state in `ValueNotifier\u003cT\u003e` can save you from\n  missing `notifyListener` calls.\n\n* [StreamBuilder](https://docs.flutter.io/flutter/widgets/StreamBuilder-class.html)\n  — Can be used with `Provide.stream` to have widgets that rebuild on\n  stream changes.\n\n","funding_links":[],"categories":["other"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogle%2Fflutter-provide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoogle%2Fflutter-provide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogle%2Fflutter-provide/lists"}