флаттер разделяет состояние между несколькими экземплярами виджета - PullRequest
1 голос
/ 09 мая 2020

В моем приложении flutter у меня есть виджет ConnectivityStatus, который отображает текущий статус подключения приложения к моему Raspberry Pi. В initState моего виджета я подписываюсь на таймер, чтобы проверять соединение каждые 5 секунд и соответствующим образом обновлять состояние, а затем отказываться от подписки при удалении.

Проблема в том, что на нескольких экранах используется ConnectivityStatus виджет, например, в настройке навигатора стека, теперь у меня есть две одновременные подписки, поскольку ни один экземпляр не удален. Это приводит к возникновению множества избыточных, ненужных запросов.

Что мне действительно нужно, так это либо поделиться одним экземпляром виджета на нескольких экранах, либо иметь одно глобальное состояние, к которому могут обращаться несколько экземпляров.

Как я могу достичь этого или какие другие рекомендуемые решения моей проблемы?

Ответы [ 3 ]

1 голос
/ 09 мая 2020

Я предлагаю использовать Provider и создать RPIService, который отправляет поток данных о состоянии подключения.

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 голосов
/ 09 мая 2020

Другой способ добиться этого - использовать GlobalKey, поскольку это официальный способ Flutter поделиться одним состоянием виджета в приложении.

В файле key.dart:

final GlobalKey<ConnectivityStatusState> connectivityStatusKey = GlobalKey();

Когда вы создаете свой ConnectivityStatus виджет:

ConnectivityStatus(
  key: connectivityStatusKey,
  ...
)

Где вы хотите получить доступ к состоянию ConnectivityStatus:

connectivityStatusKey.currentState.anythingPublicInThisState()

Чтобы использовать это, убедитесь, что ваш класс состояния это publi c (без _), а виджет ConnectivityStatus присутствует и уникальный в дереве виджетов.

Надеюсь, это поможет!

0 голосов
/ 09 мая 2020

Самый простой способ добиться этого - использовать InheritedWidget для передачи ConnectivityStatus нисходящим виджетам. https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html

Вы также можете изучить другие решения для управления состоянием, такие как Provider https://pub.dev/packages/provider или Bloc https://pub.dev/packages/flutter_bloc

...