如何动态更改文本小部件的文本和颜色/按钮的小部件文本和颜色?

时间:2021-04-12 15:37:12

标签: android flutter dart flutter-layout setstate

背景:我正在创建一个应用程序,应动态向用户显示互联网连接状态。结果已经显示,但我希望动态更改背景颜色。我试图在 setState() 中实现它,但文本颜色没有改变。而且我不知道如何在没有 onPressed 的情况下在按钮内实现 setState()。 主要代码:

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 代码:

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);
  }
}

在图像中,我的代码显示为离线..但我希望在状态旁边离线,如图所示,并且当状态在线时,背景颜色应动态更改。我该如何实施? screenshot

1 个答案:

答案 0 :(得分:1)

大功告成,您只需要将所有功能放在已设置的流侦听器中,而不是放在构建方法中。

由于您已经有一个监听连接状态变化的监听器,该监听器只需要更新一个 Color 变量。这是一个简化的示例。

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
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

enter image description here