Reputation: 151
Background: I am creating one app, where the internet connection status should be shown to the user dynamically. The result is already showing but I want the background color to be changed dynamically. I tried to implement it in setState() but the text color is not getting changed. and I don't know how to implement setState() inside button without onPressed. main code:
import 'dart:async';
import 'dart:io';
import 'package:connectivity/connectivity.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:quote_app_one/components/TextStyles_Icons.dart';
import 'package:quote_app_one/utils/HexColor.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Color _newAppBgColor = HexColor("#111328");
Map _source = {ConnectivityResult.none: false};
MyConnectivity _connectivity = MyConnectivity.instance;
@override
void initState() {
super.initState();
_connectivity.initialise();
_connectivity.myStream.listen((source) {
setState(() => _source = source);
});
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: _newAppBgColor, // navigation bar color
));
String string;
switch (_source.keys.toList()[0]) {
case ConnectivityResult.none:
string = "Offline";
break;
case ConnectivityResult.mobile:
string = "Online";
break;
case ConnectivityResult.wifi:
string = "Online";
}
//This is the setState() I have implemented
String cData = string;
setState(() {
cData = string;
if(cData == "Online"){
return Text("Online",
style: TextStyle(
color: Colors.green
),);
}
else{
return Text("Offline",
style: TextStyle(
color: Colors.red
),);
}
});
return Scaffold(
appBar: AppBar(
title: homeScreenAppBarText,
backgroundColor: _newAppBgColor,
),
backgroundColor: _newAppBgColor,
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
child: cStatusText,
),
Text( cData,
// style: TextStyle(
// color: Colors.white
// ),
)
],
),
),
new Container(
child: Row(
children: [
// custom widgets
],
),
)
],
),
),
);
}
}
class MyConnectivity {
MyConnectivity._internal();
static final MyConnectivity _instance = MyConnectivity._internal();
static MyConnectivity get instance => _instance;
Connectivity connectivity = Connectivity();
StreamController controller = StreamController.broadcast();
Stream get myStream => controller.stream;
void initialise() async {
ConnectivityResult result = await connectivity.checkConnectivity();
_checkStatus(result);
connectivity.onConnectivityChanged.listen((result) {
_checkStatus(result);
});
}
void _checkStatus(ConnectivityResult result) async {
bool isOnline = false;
try {
final result = await InternetAddress.lookup('example.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
isOnline = true;
} else
isOnline = false;
} on SocketException catch (_) {
isOnline = false;
}
controller.sink.add({result: isOnline});
}
void disposeStream() => controller.close();
}
connectivity_services code:
import 'package:flutter/material.dart';
import 'package:connectivity/connectivity.dart';
class ConnectivityChangeNotifier extends ChangeNotifier {
ConnectivityChangeNotifier() {
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
resultHandler(result);
});
}
ConnectivityResult _connectivityResult = ConnectivityResult.none;
String _pageText =
'Currently connected to no network. Please connect to a wifi network!';
ConnectivityResult get connectivity => _connectivityResult;
String get pageText => _pageText;
void resultHandler(ConnectivityResult result) {
_connectivityResult = result;
if (result == ConnectivityResult.none) {
_pageText =
'Currently connected to no network. Please connect to a wifi network!';
} else if (result == ConnectivityResult.mobile) {
_pageText =
'Currently connected to a celluar network. Please connect to a wifi network!';
} else if (result == ConnectivityResult.wifi) {
_pageText = 'Connected to a wifi network!';
}
notifyListeners();
}
void initialLoad() async {
ConnectivityResult connectivityResult =
await (Connectivity().checkConnectivity());
resultHandler(connectivityResult);
}
}
In the image, my code is displaying as offline.. but I want that offline beside status as shown in the image and the background color should change dynamically when the status is online. How can I implement this?
Upvotes: 0
Views: 663
Reputation: 5575
You're almost there, you just need to put all that functionality in the stream listener you have setup and not in the build method.
Since you already have a listener following changes in connectivity status, that listener just needs to update a Color
variable. Here's a simplified example.
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Color _newAppBgColor = HexColor("#111328");
// these 2 get updated on connectivity changes
Color statusColor = Colors.red;
String cData = 'Offline';
Map _source = {ConnectivityResult.none: false};
MyConnectivity _connectivity = MyConnectivity.instance;
@override
void initState() {
super.initState();
_connectivity.initialise();
_connectivity.myStream.listen((source) {
setState(() {
_source = source;
_updateStatusText(); // moved from build method to listener
});
});
}
void _updateStatusText() {
switch (_source.keys.toList()[0]) {
case ConnectivityResult.none:
cData = "Offline";
statusColor = Colors.red;
break;
case ConnectivityResult.mobile:
cData = "Online";
statusColor = Colors.green;
break;
case ConnectivityResult.wifi:
cData = "Online";
statusColor = Colors.green;
}
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: _newAppBgColor, // navigation bar color
));
return Scaffold(
appBar: AppBar(
// title: homeScreenAppBarText, // didn't have the origin of homeScreenAppBarText to test this
title: Text('Demo'),
backgroundColor: _newAppBgColor,
),
backgroundColor: _newAppBgColor,
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
// child: cStatusText, // didn't have the origin of cStatusText to test this
child: Text('status',
style: TextStyle(
color:
statusColor)),
),
Text(
cData, // this updates on change in connectivity status
style: TextStyle(
color:
statusColor, // this updates on change in connectivity status
),
)
],
),
),
new Container(
child: Row(
children: [
// custom widgets
],
),
)
],
),
),
);
}
}
Upvotes: 1