三元条件没有重建我的小部件 - Flutter

Posted

技术标签:

【中文标题】三元条件没有重建我的小部件 - Flutter【英文标题】:Ternary condition is not rebuilding my widget - Flutter 【发布时间】:2021-09-11 22:49:37 【问题描述】:

我需要我的“ENCEENDER”和“APAGAR”按钮在我点击它们并通过蓝牙发送一些数据后改变它们的颜色,但它们只有在我进行热重载后才会改变。不知道错误是否在三元条件下,我在前一个小部件上的逻辑几乎相同,并且当我点击“SINCRONIZAR”时更改按钮效果很好

这是我的代码:

import 'package:douglas_app/controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:loading_indicator/loading_indicator.dart';



// ignore: use_key_in_widget_constructors
class SyncDouglas extends StatelessWidget 


  /* 

COLOR FONDO:

Color.fromRGBO(22, 22, 35, 1),

COLOR BORDE NARANJA:

Color.fromRGBO(225, 139, 0, 1),

COLOR FUENTE:

Color(0xffCCCCCC)



 */

  @override
  Widget build(BuildContext context) 

    
    return GetBuilder<PruebaBlue>(
        init: PruebaBlue(''),
        builder: (_) => Scaffold(
              backgroundColor: const Color.fromRGBO(22, 22, 35, 1),
              body: Center(
                child: AnimatedSwitcher(
                  duration: const Duration(milliseconds: 500),
                  child: !_.isScanningForDevices
                      ? GestureDetector(
                          onTap: () => _.scanForDevices(),
                          child: Container(
                            width: 150,
                            height: 150,
                            child: const Center(
                              child: Text("Sincronizar",
                                  textScaleFactor: 1.4,
                                  textAlign: TextAlign.center,
                                  style: TextStyle(color: Colors.black)),
                            ),
                            decoration: BoxDecoration(
                                shape: BoxShape.circle,
                                border: Border.all(color: const Color.fromRGBO(22, 22, 35, 1)),
                                color: Colors.yellow),
                          ),
                        )
                      : AnimatedSwitcher(
                          duration: const Duration(milliseconds: 500),
                          child: _.isScanningForDevices &&
                                  !_.isConnectedToCharacteristic
                              ? SizedBox(
                                  width:
                                      MediaQuery.of(context).size.width * 0.9,
                                  child: Stack(
                                    children: [
                                      Center(
                                        child: LoadingIndicator(
                                          indicatorType:
                                              Indicator.ballScaleMultiple,
                      ),
                                      ),
                                      const Center(
                                          child: Text(
                                        "Sincronizando",
                                        textScaleFactor: 1.4,
                                        style: TextStyle(color: Colors.white),
                                      ))
                                    ],
                                  ),
                                )
                              :  Column(
                                mainAxisAlignment:
                                    MainAxisAlignment.center,
                                children: [
                                  Container(
                                    width: 150,
                                    height: 150,
                                    child: const Center(
                                      child: Text("Sincronizado",
                                          
                                          textScaleFactor: 1.4,
                                          textAlign: TextAlign.center,
                                          style: TextStyle(
                                              color: Colors.black)),
                                    ),
                                    decoration: const BoxDecoration(
                                        shape: BoxShape.circle,
                                        color: Color.fromRGBO(248, 243,43, 1),),
                                  ),

                                  
                                    const SizedBox(height:10),
                                    Row(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      children: [
                                        GestureDetector(
                                          onTap: () async 
                                            await _.sendDataToDevice('e');
                                          ,
                                            child: Container(
                                              width: MediaQuery.of(context)
                                                      .size
                                                      .width *
                                                  0.35,
                                              decoration: BoxDecoration(
                                                  color: !_.isOn
                                                      ? Colors.green
                                                      : Colors.grey,
                                                  borderRadius:
                                                      BorderRadius.circular(
                                                          10)),
                                              margin:
                                                  const EdgeInsets.all(8.0),
                                              padding:
                                                  const EdgeInsets.all(12.0),
                                              child: const Text("Encender",
                                                  textScaleFactor: 1.4,
                                                  textAlign: TextAlign.center,
                                                  style: TextStyle(
                                                      color: Colors.white)))
                                          
                                        ),
                                        GestureDetector(
                                      onTap: () async
                                          await  _.sendDataToDevice('a');
                                          ,
                                      child: Container(
                                        width: MediaQuery.of(context)
                                                .size
                                                .width *
                                            0.35,
                                        decoration: BoxDecoration(
                                            color:
                                                _.isOn
                                                    ? Colors.red
                                                    : Colors.grey,
                                            borderRadius:
                                                BorderRadius.circular(
                                                    10)),
                                        padding:
                                            const EdgeInsets.all(10.0),
                                        margin:
                                            const EdgeInsets.all(12.0),
                                        child: const Text("Apagar",
                                            textAlign: TextAlign.center,
                                            textScaleFactor: 1.4,
                                            style: TextStyle(
                                                color: Colors.white)),
                                      )),
                                      ],
                                    ),


                                    
                                  
                                ],
                              ),
                          
                               
                        ),
                ),
                
              ),
            ));
  

这是我的 SendData 代码:

sendDataToDevice(String? dataToSend) async 
    //Encoding the string
    if (dataToSend == 'e') 
      this.isOn = true;    
     else 
      this.isOn = false;
    
    dev.log("Send Data: " + dataToSend!);
    List<int> data = utf8.encode(dataToSend);
    await bluetoothCharacteristicTx.write(data, withoutResponse: false);
    
/*     print('RX');
    await bluetoothCharacteristicRx.read(); */
    
    /* print('TX');
    List<int> recibido = await bluetoothCharacteristicTx.read();
    print(utf8.decode(recibido));
    print('FIN'); */
  

  double getDistance(int rssi) 
    /*
  distance_in_meters = 10 ^ ((-69 - (<RSSI_VALUE>))/(10 * 2))
  where: -69 is a reference powerMeasured from 1 meter
  */
    double n = 2; // calibration factor range: 2-4
    return pow(10, (-69 - (rssi)) / (10 * n)).toDouble();

    
  

【问题讨论】:

1.使用 Stateful Widget 而不是 Stateless。 2. 在 @override Widget build(BuildContext context) 之前或之后将您的 sendDataToDevice() 保留在 Stateful 小部件中。 3.在setState函数中附上this.isOn = true: and this.isOn = false。 【参考方案1】:

首先,sendDataToDevice 是您的SyncDouglas 小部件的一部分吗?如果是这样,您需要将小部件转换为有状态小部件,请在 setState 函数调用中更新 isOn 属性。

否则,如果 isOn 和 sendDataToDeviceSyncDouglas 的父窗口小部件的一部分,那么您需要在那里调用 setState 来重建 SyncDouglas

【讨论】:

以上是关于三元条件没有重建我的小部件 - Flutter的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:StreamProvider 的奇怪行为,使用不完整数据重建的小部件

Flutter StatefulWidget 没有被重建

Flutter Provider 重建不必要的小部件

Flutter:检测任何在屏幕上不可见但在小部件树中的小部件的重建

如何创建自定义颤振 sdk 小部件,重建颤振和使用新的小部件

Flutter - 使用 MediaQuery 时防止重建