Il existe de multiples façons d'interagir avec d'autres stateful widgets.
1. ancestorStateOfType
La première et la plus simple est par context.ancestorStateOfType
méthode.
Généralement emballés dans une méthode statique de la Stateful
sous-classe comme ceci :
class MyState extends StatefulWidget {
static of(BuildContext context, {bool root = false}) => root
? context.rootAncestorStateOfType(const TypeMatcher<_MyStateState>())
: context.ancestorStateOfType(const TypeMatcher<_MyStateState>());
@override
_MyStateState createState() => _MyStateState();
}
class _MyStateState extends State<MyState> {
@override
Widget build(BuildContext context) {
return Container();
}
}
C'est combien de Navigator
fonctionne par exemple.
Pro:
Con:
- Tenté d'accéder
State
propriétés ou manuellement appel setState
- Nécessite d'exposer
State
sous-classe
N'utilisez pas cette méthode si vous voulez accéder à une variable. En tant que votre gadget peut pas recharger lorsque ce changement de variable.
2. Écoutable, diffuser et/ou InheritedWidget
Parfois, au lieu d'une méthode, vous pouvez accéder à certaines propriétés. La chose est, vous avez probablement voulez que vos widgets à mettre à jour chaque fois que la valeur change au cours du temps.
Dans cette situation, dart offrent Stream
et Sink
. Et flutter ajoute sur le haut de il InheritedWidget
et Listenable
comme ValueNotifier
. Elles le sont toutes relativement la même chose: s'abonner à un événement de changement de valeur lorsqu'il est couplé avec un StreamBuilder
/context.inheritFromWidgetOfExactType
/AnimatedBuilder
.
C'est la solution lorsque vous voulez que votre State
d'exposer certaines propriétés. Je ne vais pas couvrir toutes les possibilités, mais voici un petit exemple d'utilisation InheritedWidget
:
Tout d'abord, nous avons une InheritedWidget
qui exposent un count
:
class Count extends InheritedWidget {
static of(BuildContext context) =>
context.inheritFromWidgetOfExactType(Count);
final int count;
Count({Key key, @required Widget child, @required this.count})
: assert(count != null),
super(key: key, child: child);
@override
bool updateShouldNotify(Count oldWidget) {
return this.count != oldWidget.count;
}
}
Ensuite, nous avons nos State
que instancier cette InheritedWidget
class _MyStateState extends State<MyState> {
int count = 0;
@override
Widget build(BuildContext context) {
return Count(
count: count,
child: Scaffold(
body: CountBody(),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
count++;
});
},
),
),
);
}
}
Enfin, nous avons notre CountBody
qui atteignent ce exposées count
class CountBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text(Count.of(context).count.toString()),
);
}
}
Pour:
- Plus performant qu'
ancestorStateOfType
- Flux alternatif est dart seulement (fonctionne avec web) et est fortement intégré dans la langue (mots-clés comme
await for
ou async*
)
- Automic rechargement des enfants lors de la variation de la valeur
Inconvénients:
- Plus passe-partout
- Cours d'eau peut être compliqué
3. Les Notifications
Au lieu de directement de l'appel de méthodes sur State
, vous pouvez envoyer un Notification
de votre widget. Et faire State
abonnez-vous à ces notifications.
Un exemple d' Notification
serait :
class MyNotification extends Notification {
final String title;
const MyNotification({this.title});
}
Pour envoyer la notification appelez simplement dispatch(context)
sur votre notification de l'instance et il vont remonter.
MyNotification(title: "Foo")..dispatch(context)
Note: vous devez vous mettre au-dessus de la ligne de code à l'intérieur d'une classe, sinon, pas de contexte, ne peut PAS de notification d'appel.
Tout widget peut écouter les notifications envoyés par leurs enfants à l'aide de NotificationListener<T>
:
class _MyStateState extends State<MyState> {
@override
Widget build(BuildContext context) {
return NotificationListener<MyNotification>(
onNotification: onTitlePush,
child: Container(),
);
}
bool onTitlePush(MyNotification notification) {
print("New item ${notification.title}");
// true meaning processed, no following notification bubbling.
return true;
}
}
Un exemple serait l' Scrollable
, qui peut envoyer ScrollNotification
y compris de début/fin/overscroll. Ensuite utilisée par Scrollbar
savoir faire défiler des informations sans avoir accès à l' ScrollController
Pour:
- Cool réactives de l'API. Nous n'avons pas directement de faire des trucs sur
State
. Il est State
qui s'abonne aux événements déclenchés par ses enfants
- Plus d'un widget pouvez vous abonner à la même notification
- Empêche les enfants d'accéder à des indésirables
State
propriétés
Inconvénients:
- Peut ne pas convenir à votre cas d'utilisation
- Nécessite plus passe-partout