【问题标题】:Flutter Realtime Database Using a Switch使用交换机 Flutter 实时数据库
【发布时间】:2020-07-10 17:29:43
【问题描述】:

我正在尝试实现一个开关,该开关使用以下键读取和写入我的 firestore 中的 bool 值 设备/Device1/LED_STATUS/DATA

当我运行 getStatus 时,该值打印为 null,然后给出该值。小部件在函数能够给出值之前构建,因此会给出一个空断言异常并崩溃。我尝试了很多方法尝试将 initState 设置为 setState 但没有用。

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';



class SwitchPage extends StatefulWidget {
  static const String id = 'switch_screen';

  @override
  _SwitchPageState createState() => _SwitchPageState();
}

class _SwitchPageState extends State<SwitchPage> {
  final DBref = FirebaseDatabase.instance.reference();


  bool isSwitched;

  void LedOn() async {
    await DBref.child("DHT11")
        .child("Device1")
        .child("LED_STATUS")
        .update({'DATA': 'TRUE'});
  }

  void LedOFF() async {
    await DBref.child("DHT11")
        .child("Device1")
        .child("LED_STATUS")
        .update({'DATA': 'FALSE'});
  }

  Future<bool> getStatus() async {
    bool isSwitched = (await FirebaseDatabase.instance
            .reference()
            .child("DHT11/Device1/LED_STATUS/DATA")
            .once())
        .value;
    print(isSwitched);
    return isSwitched;
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          appBar: AppBar(
            title: Text('Device Center'),
          ),
          backgroundColor: Colors.white,
          body: Column(
            children: <Widget>[
              FlatButton(
                  onPressed: () {
                    getStatus();
                    print(isSwitched);
                  },
                  child: Text('TEST')),
              Switch(
                value: isSwitched,
                onChanged: (value) {
                  if (isSwitched == 'TRUE') {
                    return LedOFF();
                  } else {
                    LedOn();
                  }
                },
              )

            ],
          )),
    );
  }
}

建议后更新

我尝试了我的 TEST 按钮工作正常的建议方法,他们正在更新 firebase 数据库,但我无法实现 Switch!请帮忙!

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';


class SwitchPage extends StatefulWidget {
  static const String id = 'switch_screen';

  @override
  _SwitchPageState createState() => _SwitchPageState();
}

class _SwitchPageState extends State<SwitchPage> {
  final DBref = FirebaseDatabase.instance.reference();

  bool isSwitched;
  bool newVal;


  void LedOn() async {
    await DBref.child("DHT11")
        .child("Device1")
        .child("LED_STATUS")
        .update({'DATA': 'TRUE'});
  }

  void LedOFF() async {
    await DBref.child("DHT11")
        .child("Device1")
        .child("LED_STATUS")
        .update({'DATA': 'FALSE'});
  }

  void getStatus() async {
    String newValue = (await FirebaseDatabase.instance
            .reference()
            .child("DHT11/Device1/LED_STATUS/DATA")
            .once())
        .value;
    print(isSwitched);
    print(newValue);
    setState(() {
      if (newValue == 'TRUE') {
        isSwitched = true;
      } else {
        isSwitched = false;
      }
    });
  }


  @override
  void initState() {
    getStatus(); 
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          appBar: AppBar(
            title: Text('Device Center'),
          ),
          backgroundColor: Colors.white,
          body: Column(
            children: <Widget>[
              FlatButton(
                  onPressed: () async {
                    await getStatus();
                  },
                  child: Text('TEST STATUS')),
              FlatButton(
                  onPressed: () {
                    LedOn();
                    print('ON');
                  },
                  child: Text('LED ON')),
              FlatButton(
                  onPressed: () {
                    LedOFF();
                    print('OFF');
                  },
                  child: Text('LED OFF')),
              Switch(
                value: isSwitched,
                onChanged: (value) {
                  setState(() {
                    isSwitched = value;
                    if (isSwitched == "TRUE") {
                      return LedOFF();
                    } else if (isSwitched == "FALSE") {
                      return LedOn();
                    }
                  });
                },
              ),
            ],
          )),
    );
  }
}

【问题讨论】:

    标签: firebase flutter firebase-realtime-database switch-statement


    【解决方案1】:

    你应该在 getStatus 方法中做这样的事情

    void getStatus() async {
        String newValue = (await FirebaseDatabase.instance
                .reference()
                .child("DHT11/Device1/LED_STATUS/DATA")
                .once())
            .value;
        print(isSwitched);
        setState(() {
             if( newValue == 'TRUE' ) {
                  isSwitched = true;
            }
            else {
                 isSwitched = false;
            }
        });
      }
    

    然后在 FlatButton onPressed 你应该做这样的事情

        onPressed: () async {
            await getStatus();
            print(isSwitched);
        },          
    

    更新代码 基于新要求

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:firebase_database/firebase_database.dart';
    
    
    class SwitchPage extends StatefulWidget {
      static const String id = 'switch_screen';
    
      @override
      _SwitchPageState createState() => _SwitchPageState();
    }
    
    class _SwitchPageState extends State<SwitchPage> {
      final DBref = FirebaseDatabase.instance.reference();
    
      bool isSwitched;
      bool newVal;
    
    
      void LedOn() async {
        await DBref.child("DHT11")
            .child("Device1")
            .child("LED_STATUS")
            .update({'DATA': 'TRUE'});
      }
    
      void LedOFF() async {
        await DBref.child("DHT11")
            .child("Device1")
            .child("LED_STATUS")
            .update({'DATA': 'FALSE'});
      }
    
      void getStatus() async {
        String newValue = (await FirebaseDatabase.instance
                .reference()
                .child("DHT11/Device1/LED_STATUS/DATA")
                .once())
            .value;
        print(isSwitched);
        print(newValue);
        setState(() {
          if (newValue == 'TRUE') {
            isSwitched = true;
          } else {
            isSwitched = false;
          }
        });
      }
      
      void _handleSwitch(bool value) async {
        if( value ) {
            await LedOn();
        } else {
            await LedOFF();
        }
        setState(() {
            isSwitched = value;
        });
      }
    
    
      @override
      void initState() {
        getStatus(); 
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return SafeArea(
          child: Scaffold(
              appBar: AppBar(
                title: Text('Device Center'),
              ),
              backgroundColor: Colors.white,
              body: Column(
                children: <Widget>[
                  FlatButton(
                      onPressed: () async {
                        await getStatus();
                      },
                      child: Text('TEST STATUS')),
                  FlatButton(
                      onPressed: () {
                        LedOn();
                        print('ON');
                      },
                      child: Text('LED ON')),
                  FlatButton(
                      onPressed: () {
                        LedOFF();
                        print('OFF');
                      },
                      child: Text('LED OFF')),
                  Switch(
                    value: isSwitched,
                    onChanged: (value) async {
                      await _handleSwitch(value);
                    },
                  ),
                ],
              )),
        );
      }
    }
    

    【讨论】:

    • 我正在检查这个方法,但我的问题是如何为滚动开关实现这个?
    • 感谢您的回复我尝试了您的想法我的测试按钮工作正常但无法实现开关请帮助!
    • 你真正想用 switch 做什么?
    • 使用开关打开和关闭连接到firebase的中继设备!!
    • 请检查上面的更新代码,如果这能解决您的问题,请告诉我。
    【解决方案2】:

    你应该这样做:

      Widget _createSwitch(){
        if(isSwitched==null)
          return Center();
        return  Switch(
          value: isSwitched,
          onChanged: (value) {
            if (isSwitched == 'TRUE') {
              return LedOFF();
            } else {
              LedOn();
            }
          },
        );
      }
    

    并将 getStatus 更改为:

      void getStatus() async {
        bool mswitch = (await FirebaseDatabase.instance
                .reference()
                .child("DHT11/Device1/LED_STATUS/DATA")
                .once())
            .value;
        print(mswitch);
          setState(() {
             isSwitched=mswitch;
           });
      }
    

    【讨论】:

      猜你喜欢
      • 2021-07-03
      • 2020-10-18
      • 1970-01-01
      • 2022-12-13
      • 1970-01-01
      • 2022-08-05
      • 2019-04-13
      • 2021-03-08
      • 2021-06-09
      相关资源
      最近更新 更多