对空值使用颤振空校验算子



这是我做程序员的第一个月。我正试图开发附近的地方应用程序。当我使用以下代码我得到一个空值上使用的"null检查操作符"的错误。但是根据我看到的,或者当我打印url并手动检查时,或者当我使用if条件时,我看到没有问题或没有错误。就在我渲染屏幕时,我得到了这个错误。我想问一下,有没有人能告诉我哪里不对?提前感谢!

我得到错误的行是locationName: locationSuggestion!.query.pages[0]!.title。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_udemy_examples/http_api_data/get_location_data_final.dart';
import 'package:flutter_udemy_examples/http_api_data/get_location_names.dart';
import 'package:flutter_udemy_examples/screens/login_ekrani.dart';
import 'package:flutter_udemy_examples/screens/map_screen.dart';
import 'login_ekrani.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../banner.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_udemy_examples/http_api_data/get_location_images.dart';
// ignore: must_be_immutable
class HomeScreen extends StatefulWidget {
@override
State<HomeScreen> createState() => HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> {
LocationDataFinal? locationSuggestion;
bool isLoading = true;
@override
void initState() {
super.initState();
asyncInitState();
}
Future<void> asyncInitState() async {
await fecthlocationData();
}
Future fecthlocationData() async {
var locations = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
final double enlem = locations.latitude;
final double boylam = locations.longitude;
final url = Uri.parse(
"https://en.wikipedia.org/w/api.php?action=query&format=json&prop=coordinates%7Cpageimages%7Cdescription%7Cextracts&generator=geosearch&piprop=original&descprefersource=central&exlimit=20&exintro=1&explaintext=1&exsectionformat=plain&ggscoord=${enlem}%7C${boylam}&ggsradius=10000");
print(url);
final response = await http.get(url);
//print(response.body);
if (response.statusCode == 200) {
locationSuggestion = await locationDataFinalFromJson(response.body);
if (locationSuggestion != null) {
setState(() {
isLoading = false;
});
} else {
print("null1");
}
} else {
print("null2");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: _buildAppBar(context),
body: isLoading
? Center(
child: CircularProgressIndicator(),
)
: ListView(
children: [
MyBanner(
// info: locationSuggestion!.query.pages[0]!.description,
locationName: locationSuggestion!.query.pages[0]!.title,
imagePath:
locationSuggestion!.query.pages[0]!.original.source,
context: context,
),
MyBanner(
//info: locationSuggestion!.query.pages[1]!.description,
locationName: locationSuggestion!.query.pages[1]!.title,
imagePath:
locationSuggestion!.query.pages[1]!.original.source,
context: context,
),
MyBanner(
//  info: locationSuggestion!.query.pages[2]!.description,
locationName: locationSuggestion!.query.pages[2]!.title,
imagePath:
locationSuggestion!.query.pages[2]!.original.source,
context: context,
),
MyBanner(
//  info: locationSuggestion!.query.pages[3]!.description,
locationName: locationSuggestion!.query.pages[3]!.title,
imagePath:
locationSuggestion!.query.pages[3]!.original.source,
context: context,
),
MyBanner(
//  info: locationSuggestion!.query.pages[4]!.description,
locationName: locationSuggestion!.query.pages[4]!.title,
imagePath:
locationSuggestion!.query.pages[4]!.original.source,
context: context,
),
],
),
);
}
AppBar _buildAppBar(BuildContext context) {
return AppBar(
automaticallyImplyLeading: false,
leading: RotatedBox(
quarterTurns: 2,
child: _buildExitButton(context),
),
actions: [
_buildOpenMapButton(),
_buildCallEmergencyNumberButton(),
],
titleSpacing: 25,
shadowColor: Colors.white,
elevation: 0.0,
backgroundColor: Colors.blue[800],
//titleSpacing: Padding(padding: EdgeInsets.fromLTRB(25.85.0, 0, 25.85.0, 0)),
title: Text("Traveler Doctor"),
);
}
Widget _buildCallEmergencyNumberButton() {
return IconButton(
disabledColor: Colors.red,
color: Colors.red,
icon: Icon(Icons.phone_enabled),
tooltip: "Local emergency number",
onPressed: null,
);
}
Widget _buildOpenMapButton() {
return IconButton(
disabledColor: Colors.orangeAccent,
color: Colors.limeAccent,
icon: Icon(Icons.map_rounded),
tooltip: "Map",
enableFeedback: false,
onPressed: () => {
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) => MapScreen()))
},
);
}
}
Widget _buildExitButton(BuildContext context) {
return IconButton(
onPressed: () async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('KullaniciAdi', "");
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) => LoginEkrani()));
},
icon: Icon(
Icons.exit_to_app,
color: Colors.red,
),
tooltip: "Exit",
);
}

这是我用来解析api响应的模型

import 'dart:convert';
LocationDataFinal locationDataFinalFromJson(String str) =>
LocationDataFinal.fromJson(json.decode(str));
class LocationDataFinal {
LocationDataFinal({
required this.batchcomplete,
required this.query,
});
String batchcomplete;
Query query;
factory LocationDataFinal.fromJson(Map<String, dynamic> json) =>
LocationDataFinal(
batchcomplete: json["batchcomplete"],
query: Query.fromJson(json["query"]),
);
}
class Query {
Query({
required this.pages,
});
Map<String, Page> pages;
factory Query.fromJson(Map<String, dynamic> json) => Query(
pages: Map.from(json["pages"])
.map((k, v) => MapEntry<String, Page>(k, Page.fromJson(v))),
);
}
class Page {
Page({
required this.pageid,
required this.ns,
required this.title,
required this.index,
required this.coordinates,
required this.original,
required this.description,
required this.descriptionsource,
required this.extract,
});
int pageid;
int ns;
String title;
int index;
List<Coordinate> coordinates;
Original original;
String description;
String descriptionsource;
String extract;
factory Page.fromJson(Map<String, dynamic> json) => Page(
pageid: json["pageid"],
ns: json["ns"],
title: json["title"],
index: json["index"],
coordinates: List<Coordinate>.from(
json["coordinates"].map((x) => Coordinate.fromJson(x))),
original: json["original"] == null
? Original(
source:
"https://tigres.com.tr/wp-content/uploads/2016/11/orionthemes-placeholder-image-1.png",
width: 300,
height: 200)
: Original.fromJson(json["original"]),
description: json["description"] == null ? "asd" : json["description"],
descriptionsource:
json["descriptionsource"] == null ? " " : json["descriptionsource"],
extract: json["extract"],
);
}
class Coordinate {
Coordinate({
required this.lat,
required this.lon,
required this.primary,
required this.globe,
});
double lat;
double lon;
String primary;
Globe globe;
factory Coordinate.fromJson(Map<String, dynamic> json) => Coordinate(
lat: json["lat"].toDouble(),
lon: json["lon"].toDouble(),
primary: json["primary"],
globe: globeValues.map[json["globe"]]!,
);
}
enum Globe { EARTH }
final globeValues = EnumValues({"earth": Globe.EARTH});
class Original {
Original({
required this.source,
required this.width,
required this.height,
});
String source;
int width;
int height;
factory Original.fromJson(Map<String, dynamic> json) => Original(
source: json["source"],
width: json["width"],
height: json["height"],
);
}
class EnumValues<T> {
late Map<String, T> map;
late Map<T, String> reverseMap;
EnumValues(this.map);
}

我会经常查看这篇文章。再次提前感谢。真诚的新手程序员。

我会留下这个评论,但显然我只有足够的声誉来写答案。

在你的查询对象页面是一个Map<String, Page>,但你访问它与一个int键:locationSuggestion!.query.pages[0]!.title

要使用int键访问映射,它需要是Map<int,Page>(或List<Page>)

通过替换某种程度上解决了这个问题locationSuggestion!.query.pages[0]!.title

locationSuggestion!.query.pages.values.elementAt(0).title这种解决问题的方法为我解决了:)

最新更新