当某些全局变量发生变化时,有没有办法在 Flutter 中动态更新图标的颜色?
Is there a way to dynamically update the Color of an Icon in Flutter when some global variable changes?
我有一个全局变量,它在 MQTT 的 onConnectionSuccessful 回调中发生变化。我的 appBar 中有一个图标,我可以通过检查变量然后更新来分配它以更改颜色。我想知道是否有办法在全局变量更改时动态更改图标的颜色。我不知道我是否以错误的方式解决这个问题。本质上,我希望当我与服务器的连接发生变化时图标也会发生变化,以让用户知道他们是否已连接。
回调代码:
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');
}
}
已连接:
断开连接:
我会尽量解释清楚,但假设我们使用 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
),
),
],
);
}
}
我有一个全局变量,它在 MQTT 的 onConnectionSuccessful 回调中发生变化。我的 appBar 中有一个图标,我可以通过检查变量然后更新来分配它以更改颜色。我想知道是否有办法在全局变量更改时动态更改图标的颜色。我不知道我是否以错误的方式解决这个问题。本质上,我希望当我与服务器的连接发生变化时图标也会发生变化,以让用户知道他们是否已连接。
回调代码:
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');
}
}
已连接:
断开连接:
我会尽量解释清楚,但假设我们使用 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
),
),
],
);
}
}