Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// ignore_for_file: public_member_api_docs
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
/// A provider that exposes a [ValueNotifier] in two independent pieces.
///
/// [StoreProvider] will expose both [ValueNotifier] and [ValueNotifier.value] independently
/// to its dependents.
///
/// For the [ValueNotifier]:
///
/// ```dart
/// class MyStore extends ValueNotifier<int> {
/// MyStore(): super(0);
/// }
/// ```
///
/// it is possible to obtain the `MyStore` instance through:
///
/// ```dart
/// Provider.of<MyStore>(context);
/// ```
///
/// and the current value through:
///
/// ```dart
/// Provider.of<int>(context);
/// ```
class StoreProvider<Value, Controller extends ValueNotifier<Value>>
extends ValueDelegateWidget<Controller>
implements SingleChildCloneableWidget {
/// Allows to specify parameters to [StoreProvider].
StoreProvider({
Key key,
@required ValueBuilder<Controller> builder,
Widget child,
}) : this._(
key: key,
delegate: BuilderStateDelegate<Controller>(builder, dispose:(_, v) => v.dispose()),
updateShouldNotify: null,
child: child,
);
/// Allows to specify parameters to [StoreProvider].
StoreProvider.value({
Key key,
@required Controller value,
UpdateShouldNotify<Controller> updateShouldNotify,
Widget child,
}) : this._(
key: key,
delegate: SingleValueDelegate<Controller>(value),
updateShouldNotify: updateShouldNotify,
child: child,
);
StoreProvider._({
Key key,
@required ValueStateDelegate<Controller> delegate,
this.updateShouldNotify,
this.child,
}) : super(key: key, delegate: delegate);
/// User-provided custom logic for [InheritedWidget.updateShouldNotify].
final UpdateShouldNotify<Controller> updateShouldNotify;
@override
StoreProvider<Value, Controller> cloneWithChild(Widget child) {
return StoreProvider._(
key: key,
delegate: delegate,
updateShouldNotify: updateShouldNotify,
child: child,
);
}
/// The widget that is below the current [StoreProvider] widget in the
/// tree.
///
/// {@macro flutter.widgets.child}
final Widget child;
@override
Widget build(BuildContext context) {
assert(() {
Provider.debugCheckInvalidValueType?.call<Controller>(delegate.value);
return true;
}());
return InheritedProvider<Controller>(
value: delegate.value,
updateShouldNotify: updateShouldNotify,
child: ValueListenableProvider<Value>.value(
value: delegate.value,
child: child,
),
);
}
}
import 'package:flutter/widgets.dart';
enum _Action {
increment,
decrement,
}
class MyStore extends ValueNotifier<int> {
MyStore() : super(0);
void increment() => value++;
void decrement() => value--;
}
class Bar {}
class Initial implements Bar {}
class Loading implements Bar {}
class Error implements Bar {
Error(this.err);
final Object err;
}
class Loaded implements Bar {
Loaded(this.value);
final int value;
}
class Foo extends ValueNotifier<Bar> {
Foo() : super(Initial());
Future<void> fetch() async {
value = Loading();
try {
final result = await Future<int>.delayed(Duration(seconds: 1));
value = Loaded(result);
} catch (err) {
value = Error(err);
}
}
}
@love179902483

This comment has been minimized.

Copy link

love179902483 commented Feb 3, 2020

看不懂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.