簡體   English   中英

Flutter,setState() 在 Release 但在 Debug 中無法正常工作

[英]Flutter, setState() not working properly in Release but in Debug

我有一個在 FutureBuilder 內部構建的堆棧,堆棧的一部分是一個 ElevatedButton,它專注於我在地圖上的當前位置,這也是堆棧的一部分。

我的想法是,當我點擊地圖的標記時,布爾值被設置為 false(onMarkerTap),因此按鈕消失,當我再次點擊地圖(onTap)時,按鈕再次出現。 我通過使用 setState() 方法來做到這一點。

問題是,在使用調試模式時,所有這些代碼都可以正常工作,但是一旦我使用釋放模式,按鈕就會消失並且永遠不會回來。

class MapComponent extends StatefulWidget {
  const MapComponent({Key? key}) : super(key: key);

  @override
  State<MapComponent> createState() => MapSampleState();
}

class MapSampleState extends State<MapComponent> {


  ...

  bool _focusLocationVisible = true;

  @override
  void initState() {
    // TODO: implement initState

    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }


  void setFocusButton(bool state){
    setState(() {
      _focusLocationVisible = state;
    });
  }

  @override
  Widget build(BuildContext context) {

    return FutureBuilder(
      
        future: _getDataFuture, 
        builder: (BuildContext jsoncontext, AsyncSnapshot snapshot) {
          if (!snapshot.hasData) {
            return (const Center(child: CircularProgressIndicator()));
          } else {
            ... 
          }

          var size = MediaQuery.of(context).size;

          return Stack(
            children: [
              FlutterMap(
                mapController: mapController,
                layers: [
                  TileLayerOptions(...),
                  LocationMarkerLayerOptions(),
                  MarkerClusterLayerOptions(

                    ...

                    onMarkerTap:(Marker marker)=>{

                      setFocusButton(false)

                    },

                    popupOptions: PopupOptions(
                        popupController: _popupController,
                        popupSnap: PopupSnap.mapBottom,
                        popupAnimation: PopupAnimation.fade(
                            duration: Duration(milliseconds: 200)),
                        popupBuilder: (_, marker) {
                          
                          return DraggableScrollableSheet(...);
                        }),
                  ),
                ],




                options: MapOptions(
                  onTap: (TapPosition, LatLang) =>
                      {
                        _popupController.hideAllPopups(),
                        setFocusButton(true),
                        },

                  ...

                  plugins: [
                    MarkerClusterPlugin(),
                    LocationMarkerPlugin(
                      //centerOnLocationUpdate: _centerOnLocationUpdate,
                      centerCurrentLocationStream: _centerCurrentLocationStreamController.stream,
                      centerAnimationDuration: Duration(milliseconds: 500),
                    )
                  ],
                ),

              ),
             if(_focusLocationVisible == true)  
              Positioned(
                right:  20,
                bottom: 40,

                //right:  _buttonrightPosition,
                //bottom: _buttonbottomPosition,
                  child: AnimatedOpacity(
                    opacity: _focusLocationVisible ? 1.0 : 0.0,
                    duration: const Duration(milliseconds: 500),
                    child: FloatingActionButton(
                          backgroundColor: Theme.of(context).bottomAppBarColor,
                          heroTag: null,
                          onPressed: () async {
                            // Location location = Location();
                            // LocationData curloc = await location.getLocation();
                            _centerCurrentLocationStreamController.add(16);
                            //mapController.move(LatLng(curloc.latitude!, curloc.longitude!),16);
                          },
                          child: const Icon(
                            Icons.my_location,
                            color: Colors.white,
                          ),
                        ),
                      
                  ),
              ),

            ],
          );
        });
  }
}


我已經嘗試直接在 onTaps 內部調用 setState 方法,或者只是將按鈕移出站點,或者在構建方法開始時將另一個布爾值設置為構建方法之外的布爾值,但是沒有任何效果。

預先感謝您的回答。

我也是 Flutter 的新手,但是當我遇到類似情況時,我用 ValueListenableBuilder 包裝了小部件並將布爾值設置為 ValueNotifier。 它對我有用。

class MapComponent extends StatefulWidget {
  const MapComponent({Key? key}) : super(key: key);

  @override
  State<MapComponent> createState() => MapSampleState();
}

class MapSampleState extends State<MapComponent> {


  ...

  @override
  void initState() {
    // TODO: implement initState

    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    
    ValueNotifier<bool> _focusLocationVisible = ValueNotifier(true);

    return FutureBuilder(
      
        future: _getDataFuture, 
        builder: (BuildContext jsoncontext, AsyncSnapshot snapshot) {
          if (!snapshot.hasData) {
            return (const Center(child: CircularProgressIndicator()));
          } else {
            ... 
          }

          var size = MediaQuery.of(context).size;

          return ValueListenableBuilder(
                              valueListenable: _focusLocationVisible,
                              builder: (context, _value, _) {return Stack(
            children: [
              FlutterMap(
                mapController: mapController,
                layers: [
                  TileLayerOptions(...),
                  LocationMarkerLayerOptions(),
                  MarkerClusterLayerOptions(

                    ...

                    onMarkerTap:(Marker marker)=>{

                      _focusLocationVisible.value = false

                    },

                    popupOptions: PopupOptions(
                        popupController: _popupController,
                        popupSnap: PopupSnap.mapBottom,
                        popupAnimation: PopupAnimation.fade(
                            duration: Duration(milliseconds: 200)),
                        popupBuilder: (_, marker) {
                          
                          return DraggableScrollableSheet(...);
                        }),
                  ),
                ],




                options: MapOptions(
                  onTap: (TapPosition, LatLang) =>
                      {
                        _popupController.hideAllPopups(),
                        _focusLocationVisible.value = false,
                        },

                  ...

                  plugins: [
                    MarkerClusterPlugin(),
                    LocationMarkerPlugin(
                      //centerOnLocationUpdate: _centerOnLocationUpdate,
                      centerCurrentLocationStream: _centerCurrentLocationStreamController.stream,
                      centerAnimationDuration: Duration(milliseconds: 500),
                    )
                  ],
                ),

              ),
             if(_focusLocationVisible == true)  
              Positioned(
                right:  20,
                bottom: 40,

                //right:  _buttonrightPosition,
                //bottom: _buttonbottomPosition,
                  child: AnimatedOpacity(
                    opacity: _focusLocationVisible ? 1.0 : 0.0,
                    duration: const Duration(milliseconds: 500),
                    child: FloatingActionButton(
                          backgroundColor: Theme.of(context).bottomAppBarColor,
                          heroTag: null,
                          onPressed: () async {
                            // Location location = Location();
                            // LocationData curloc = await location.getLocation();
                            _centerCurrentLocationStreamController.add(16);
                            //mapController.move(LatLng(curloc.latitude!, curloc.longitude!),16);
                          },
                          child: const Icon(
                            Icons.my_location,
                            color: Colors.white,
                          ),
                        ),
                      
                  ),
              ),

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

希望這對你也有效。

請注意,setState 可能會重新加載 Futurebuilder。 按照建議,積極使用組合小部件。 ValueNotifier 適用於小型項目,但對於大型項目,您的代碼將難以理解。

class MapComponent extends StatelessWidget {
  const MapComponent({Key? key}) : super(key: key);


  @override
  Widget build(BuildContext context) {
    return FutureBuilder(

        future: _getDataFuture,
        builder: (BuildContext jsoncontext, AsyncSnapshot snapshot) {
          if (snapshot.connectionState = ConnectionState.waiting) {
            return (const Center(child: CircularProgressIndicator()));
          } else if (!snapshot.hasData) {
            return Text("No data");
          }


          final data = snapshot.data;

          var size = MediaQuery
              .of(context)
              .size;

          return BuildStack(yourData: data);
        });
  }

}


class BuildStack extends StatefulWidget {
  final dynamic yourData;

  const BuildStack({Key? key, required this.yourData}) : super(key: key);

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

class _BuildStackState extends State<BuildStack> {

  late bool _focusLocationVisible = true;

  @override
  void initState() {
    super.initState();
    _focusLocationVisible = true;
  }


  void setFocusButton() {
    setState(() {
      _focusLocationVisible = !_focusLocationVisible;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        FlutterMap(
          mapController: mapController,
          layers: [
            TileLayerOptions(...),
            LocationMarkerLayerOptions(),
            MarkerClusterLayerOptions(


              onMarkerTap: (Marker marker) =>
                  setFocusButton()
              ,

              popupOptions: PopupOptions(
                  popupController: _popupController,
                  popupSnap: PopupSnap.mapBottom,
                  popupAnimation: PopupAnimation.fade(
                      duration: const Duration(milliseconds: 200)),
                  popupBuilder: (_, marker) {
                    return DraggableScrollableSheet(...);
                  }),
            ),
          ],


          options: MapOptions(
            onTap: (TapPosition, LatLang) =>
            {
              _popupController.hideAllPopups(),
              setFocusButton(),
            },


            plugins: [
              MarkerClusterPlugin(),
              LocationMarkerPlugin(
                //centerOnLocationUpdate: _centerOnLocationUpdate,
                centerCurrentLocationStream: _centerCurrentLocationStreamController
                    .stream,
                centerAnimationDuration: const Duration(
                    milliseconds: 500),
              )
            ],
          ),

        ),
        if(_focusLocationVisible)
          Positioned(
            right: 20,
            bottom: 40,

            //right:  _buttonrightPosition,
            //bottom: _buttonbottomPosition,
            child: AnimatedOpacity(
              opacity: _focusLocationVisible ? 1.0 : 0.0,
              duration: const Duration(milliseconds: 500),
              child: FloatingActionButton(
                backgroundColor: Theme
                    .of(context)
                    .bottomAppBarColor,
                heroTag: null,
                onPressed: () async {
                  // Location location = Location();
                  // LocationData curloc = await location.getLocation();
                  _centerCurrentLocationStreamController.add(16);
                  //mapController.move(LatLng(curloc.latitude!, curloc.longitude!),16);
                },
                child: const Icon(
                  Icons.my_location,
                  color: Colors.white,
                ),
              ),

            )
            ,
          )
        ,

      ]
      ,
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM