有没有办法在设置的全局变量发生变化时动态更新 Flutter 中图标的颜色?

问题描述 投票:0回答:1

我有一个全局变量,该变量在 MQTT 的 onConnectionSuccessful 回调中发生更改。我的应用程序栏中有一个图标,我可以通过检查变量然后更新来分配该图标以在点击时更改颜色。我想知道是否有一种方法可以在全局变量发生变化时动态更改图标的颜色。我不知道我是否以错误的方式处理这件事。本质上,我希望当我与服务器的连接发生变化时图标也发生变化,以让用户知道他们是否已连接。

回调代码:

void onConnected() {
 client.subscribe('topic', MqttQos.atMostOnce);
 globals.isMqttConnected = true;
 print('OnConnected client callback - Client connection was successful');}

当前图标代码:

            child: GestureDetector(
             onTap: () {
               setState(() {});
             },
             child: (globals.isMqttConnected == true)
                 ? const Icon(
                     Icons.bar_chart_rounded,
                     size: 26.0,
                     color: Colors.white,
                   )
                 : const Icon(
                     Icons.bar_chart_rounded,
                     size: 26.0,
                     color: Colors.grey,
                   ),
           ),

OnDisconnected 回调:

void onDisconnected() {
 globals.isMqttConnected = false;
 print('EXAMPLE::OnDisconnected client callback - Client disconnection');
 if (client.connectionStatus!.disconnectionOrigin ==
     MqttDisconnectionOrigin.solicited) {
   print('EXAMPLE::OnDisconnected callback is solicited, this is correct');
 } else {
   print(
       'EXAMPLE::OnDisconnected callback is unsolicited or none, this is incorrect - exiting');
   // exit(-1);
 }
 if (pongCount == 3) {
   print('EXAMPLE:: Pong count is correct');
 } else {
   print('EXAMPLE:: Pong count is incorrect, expected 3. actual $pongCount');
 }

}

已连接:

已断开连接:

flutter dart callback
1个回答
1
投票

我会尽力解释清楚,但是假设我们使用Provider,一个简单的状态管理工具,我们要做的第一件事就是创建我们的服务,在这种情况下,您的 onConnected 和 onDisconnected 函数将在其中被发现。

class OnlineService with ChangeNotifier { // to notify the listeners

   bool _isConnected = false; // varible that gonna change

   bool get isConnected => _isConnected; // getter

   void onConnected() {
     client.subscribe('topic', MqttQos.atMostOnce);
     globals.isMqttConnected = true;
     print('OnConnected client callback - Client connection was successful');

     _isConnected = true; // now connected
     notifyListeners(); // this is important to change the UI
   }

   void onDisconnected() {
     globals.isMqttConnected = false;
     print('EXAMPLE::OnDisconnected client callback - Client disconnection');

     _isConnected = false; // now disconnected
     notifyListeners(); // this is important to change the UI
       
     if (client.connectionStatus!.disconnectionOrigin ==    MqttDisconnectionOrigin.solicited) {
         print('EXAMPLE::OnDisconnected callback is solicited, this is correct');
     } else {
         print('EXAMPLE::OnDisconnected callback is unsolicited or none, this is incorrect - exiting');  // exit(-1);
     }
     if (pongCount == 3) {
         print('EXAMPLE:: Pong count is correct');
     } else {
       print('EXAMPLE:: Pong count is incorrect, expected 3. actual $pongCount');
      }
   }

}

现在我做了一个小demo,需要大家下载Provider包。

看,我接下来做的很简单,我通过按钮模拟了连接和断开连接(在你的情况下,你可以用另一种方式),现在,当我们需要调用一些引用服务的变量或函数时,我们有使用 MultiProvider 全局启动它,这将允许该服务位于所有应用程序中。

正是出于这个原因,在我的HomePage中,我通过以下方式初始化它:

final OnlineService newsService = Provider.of<OnlineService>(context);

有了它,我可以获得我的函数,并以同样的方式获得变量 isConnected;你要做的就是在客户端连接时调用这些函数,而不是占用按钮,你就会看到变化。

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => OnlineService()), // set the service in all the app
      ],
      child: MaterialApp(
        title: 'Material App',
        theme: myTheme,
        debugShowCheckedModeBanner: false,
        home: const HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final OnlineService newsService = Provider.of<OnlineService>(context); // instance of the service

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        MaterialButton(
          onPressed: () {
            newsService.onConnected(); // connected
          },
          child: const Text("Connected"),
        ),
        MaterialButton(
          onPressed: () {
            newsService.onDisconnected(); // disconnected
          },
          child: const Text("Disconnected"),
        ),
        Center(
          child: Icon(
            Icons.bar_chart_rounded,
            size: 26.0,
            color: newsService.isConnected ? Colors.white : Colors.grey, // like this you change the color
          ),
        ),
      ],
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.