En mi aplicación flutter, tengo un widget ConnectivityStatus que muestra el estado de conexión actual de la aplicación a mi raspberry pi. En el initState de mi widget, me suscribo a un temporizador para verificar la conexión cada 5 segundos y actualizo el estado en consecuencia, luego me doy de baja al eliminarlo.

El problema es que, cuando varias pantallas usan el widget ConnectivityStatus, como en una configuración de navegador de pila, ahora tengo dos suscripciones simultáneas ya que ninguna de las instancias ha eliminado. Esto provoca que se produzcan muchas solicitudes redundantes e innecesarias.

Lo que realmente quiero es compartir una sola instancia del widget en varias pantallas o tener un estado global al que puedan acceder varias instancias.

¿Cómo puedo lograr esto o cuáles son otras soluciones recomendadas para mi problema?

0
John Schlachtenhaufen 9 may. 2020 a las 00:34

3 respuestas

La mejor respuesta

La forma más sencilla de lograr esto sería usar InheritedWidget para pasar el ConnectivityStatus a los widgets descendentes. https://api.flutter.dev/flutter/widgets/InheritedWidget-class. html

También puede buscar otras soluciones de administración del estado, como Proveedor https://pub.dev/packages/provider o bloque https://pub.dev/packages/flutter_bloc

0
dshukertjr 8 may. 2020 a las 21:45

Sugiero usar el Proveedor y crear un RPIService que envíe un flujo de estado de conectividad.

class RPIService {
  var RPIstatus = ValueNotifier<Status>(Status('offline'));

RPIService(){

rpi...listen((cstatus){
RPIstatus.add(Status(cstatus));

});

}}

class Status {
final String statusMessage;
 Status(this.statusMessage);
} 

Main.dart

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [

       Provider<UserService>(
       create: (context) => UserService(),
       lazy: false,

       ),
        StreamProvider<Status>(
          create: (context) =>
              Provider.of<RPIService>(context, listen: false).RPIstatus,
        ),
      ],
      child: MaterialApp(
        title: 'Your app',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: YourHome(),
      ),
    );
  }
}

YourHome.dart

class YourHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<Status>(builder: (context, status, _) {
      return Scaffold(
        body: Text(status.status),
      );
    });
  }
}
0
SempaiLeo 8 may. 2020 a las 22:01

Otra forma de lograr esto es usar GlobalKey, ya que es la forma oficial de Flutter de compartir un solo estado de widget en la aplicación.

En un archivo key.dart:

final GlobalKey<ConnectivityStatusState> connectivityStatusKey = GlobalKey();

Cuando crea su widget ConnectivityStatus:

ConnectivityStatus(
  key: connectivityStatusKey,
  ...
)

Donde desea acceder al estado ConnectivityStatus:

connectivityStatusKey.currentState.anythingPublicInThisState()

Para usar esto, asegúrese de que su clase de estado sea pública (sin _) y que el widget ConnectivityStatus esté presente y único en el árbol de widgets.

¡Espero que esto ayude!

0
na2axl 8 may. 2020 a las 22:55