繁体   English   中英

flutter_google_places Null 安全问题

[英]flutter_google_places Null Safety Issue

我实现了 flutter_google_place package,但是在我使用的 Flutter 版本 (2.10.1) 中,null 安全版本给我带来了一些问题。 代码是这样的:

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

  @override
  State<SearchButton> createState() => _SearchButtonState();
}

class _SearchButtonState extends State<SearchButton> {
  final _destinationController = TextEditingController();
  final ApiKey = "XYZ";

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

  @override
  Widget build(BuildContext context) {
    final newLocation = Provider.of<ClientRequest>(context);
    final sessionToken = const Uuid().v4();
    Mode _mode = Mode.overlay;

    void onError(PlacesAutocompleteResponse response) {
      SnackBar(
        content: Text(response.errorMessage),
      );
    }

    Future<void> displayPrediction(Prediction p) async {
      if (p != null) {
        GoogleMapsPlaces _places = GoogleMapsPlaces(
          apiKey: ApiKey,
          apiHeaders: await const GoogleApiHeaders().getHeaders(),
        );
        PlacesDetailsResponse detail =
            await _places.getDetailsByPlaceId(p.placeId);
        final lat = detail.result.geometry?.location.lat;
        final lng = detail.result.geometry?.location.lng;
        SnackBar(
          content: Text("${p.description} - $lat/$lng"),
        );
        print(detail);
      }
    }

    Future<void> _handlePressButton() async {
      Prediction p = await PlacesAutocomplete.show(
        context: context,
        apiKey: ApiKey,
        onError: onError,
        mode: _mode,
        language: "fr",
        decoration: InputDecoration(
          hintText: 'Search',
          focusedBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(20),
            borderSide: const BorderSide(
              color: Colors.white,
            ),
          ),
        ),
        components: [Component(Component.country, "mx")],
      );

      displayPrediction(p);
    }

    return MaterialButton(
      onPressed: _handlePressButton,
      child: Container(
        padding: const EdgeInsets.only(left: 3, right: 3),
        child: Container(
          decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(20),
              boxShadow: const [
                BoxShadow(
                  color: Colors.grey,
                  spreadRadius: 1,
                  blurRadius: 3,
                  offset: Offset(0, 3),
                ),
              ]),
          child: TextField(
            controller: _destinationController,
            decoration: InputDecoration(
              enabled: false,
              prefixIcon: const Icon(Icons.search),
              filled: true,
              fillColor: const Color(0xffEDEDED),
              hintText: 'Ingresa una nueva dirección',
              contentPadding:
                  const EdgeInsets.only(left: 14.0, bottom: 8.0, top: 8.0),
              disabledBorder: OutlineInputBorder(
                borderSide: const BorderSide(color: Colors.white),
                borderRadius: BorderRadius.circular(20),
              ),
              border: const OutlineInputBorder(),
            ),
          ),
        ),
      ),
    );
  }
}

错误在:response.errorMessage -> The argument type 'String?' 不能分配给参数类型 'String' p.placeId -> The argument type 'String?' 不能分配给参数类型“String”。 await PlacesAutocomplete.show -> “预测”类型的值? 不能分配给“预测”类型的变量。 尝试更改变量的类型,或将右侧类型转换为“预测”。

任何线索如何解决这个问题?

基本上你应该写Text(response.errorMessage,),每当你在X? can not be assigned to X X? can not be assigned to X ,只需要在末尾加一个感叹号即可。

我认为您的 IDE 应该警告您在哪里修复它,但根据我对消息的理解,您需要更改这三个值。

检查下面的注释代码。

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

  @override
  State<SearchButton> createState() => _SearchButtonState();
}

class _SearchButtonState extends State<SearchButton> {
  final _destinationController = TextEditingController();
  final ApiKey = "XYZ";

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

  @override
  Widget build(BuildContext context) {
    final newLocation = Provider.of<ClientRequest>(context);
    final sessionToken = const Uuid().v4();
    Mode _mode = Mode.overlay;

    void onError(PlacesAutocompleteResponse response) {
      SnackBar(
        content: Text(response.errorMessage),
      );
    }

    /// This prediction value is expected to be a nullable type, so you 
    /// should make it nullable
    Future<void> displayPrediction(Prediction? p) async {
      if (p != null) {
        GoogleMapsPlaces _places = GoogleMapsPlaces(
          apiKey: ApiKey,
          apiHeaders: await const GoogleApiHeaders().getHeaders(),
        );
        /// p.placeId here is getting the value from p variable and since it
        /// might be null but it is checked to be not, we can put an exclamation mark
        PlacesDetailsResponse detail =
            await _places.getDetailsByPlaceId(p!.placeId);
        final lat = detail.result.geometry?.location.lat;
        final lng = detail.result.geometry?.location.lng;
        SnackBar(
          content: Text("${p.description} - $lat/$lng"),
        );
        print(detail);
      }
    }

    Future<void> _handlePressButton() async {
      /// This value here can be null, so it should be assigned as nullable
      /// I would also suggest to use final
      final p = await PlacesAutocomplete.show(
        context: context,
        apiKey: ApiKey,
        onError: onError,
        mode: _mode,
        language: "fr",
        decoration: InputDecoration(
          hintText: 'Search',
          focusedBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(20),
            borderSide: const BorderSide(
              color: Colors.white,
            ),
          ),
        ),
        components: [Component(Component.country, "mx")],
      );

      displayPrediction(p);
    }

    return MaterialButton(
      onPressed: _handlePressButton,
      child: Container(
        padding: const EdgeInsets.only(left: 3, right: 3),
        child: Container(
          decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(20),
              boxShadow: const [
                BoxShadow(
                  color: Colors.grey,
                  spreadRadius: 1,
                  blurRadius: 3,
                  offset: Offset(0, 3),
                ),
              ]),
          child: TextField(
            controller: _destinationController,
            decoration: InputDecoration(
              enabled: false,
              prefixIcon: const Icon(Icons.search),
              filled: true,
              fillColor: const Color(0xffEDEDED),
              hintText: 'Ingresa una nueva dirección',
              contentPadding:
                  const EdgeInsets.only(left: 14.0, bottom: 8.0, top: 8.0),
              disabledBorder: OutlineInputBorder(
                borderSide: const BorderSide(color: Colors.white),
                borderRadius: BorderRadius.circular(20),
              ),
              border: const OutlineInputBorder(),
            ),
          ),
        ),
      ),
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM