当我从SQLLite DB中读取保存的Erros is type 'List<dynamic>' is not a subtype of type 'List<LatLng>'
时收到此错误UserRoute
。我首先尝试使用json编码器/解码器直接对列表进行编码/解码,然后添加了一个额外的步骤,即在对列表进行编码之前分别对每个坐标进行编码,但是当读回时会出现错误。怪异的行为是,我仅在第一次构建时得到错误,在热重启时会读取db fine。我在BlocListener中打印加载的路由
state received
I/flutter (17812): saved route are 4
I/flutter (17812): [Route: {RO-f3c86115-3f85-4542-88e2-ad374991bbf7,ffff,0.22044000000000002,0.22044000000000002,[LatLng(latitude:44.500714, longitude:11.335623), LatLng(latitude:44.500714, longitude:11.335623),
但是屏幕的ListView中没有显示任何元素。另外,仍然仅在第一次构建时发生,仅在弹出SelectRouteScreen
时才会调度bloc事件,而在加载时不会调度。你能看到我做错了吗?这是模型类:
class UserRoute {
final String routeId;
final String routeName;
final String routeDistance;
final String routeDuration;
final List<LatLng> coordinates;
const UserRoute(
{@required this.routeId,
@required this.routeName,
@required this.routeDistance,
@required this.routeDuration,
@required this.coordinates});
@override
List<Object> get props =>
[routeId, routeName, routeDistance, routeDuration, coordinates];
@override
String toString() =>
'Route: {$routeId,$routeName,$routeDistance,$routeDuration,$coordinates}';
factory UserRoute.fromMap(Map<String, dynamic> map) => new UserRoute(
routeId: map["routeId"],
routeName: map["routeName"],
routeDistance: map["routeDistance"],
routeDuration: map["routeDuration"],
// coordinates: json
// .decode(map["coordinates"])
coordinates: latLngFromJson(map["coordinates"]),
); //todo check if correct
Map<String, dynamic> toMap() => {
"routeId": routeId,
"routeName": routeName,
"routeDistance": routeDistance,
"routeDuration": routeDuration,
// "coordinates": json.encode(coordinates)
"coordinates": latLngToJson(coordinates)
};
}
List<LatLng> latLngFromJson(String str) {
final jsonData = json.decode(str);
return new List<LatLng>.from(jsonData.map((x) => fromJson(x)));
}
String latLngToJson(List<LatLng> data) {
final dyn = new List<dynamic>.from(data.map((x) => toJson(x)));
return json.encode(dyn);
}
LatLng fromJson(Map<String, dynamic> json) => new LatLng(
json["lat"].toDouble(),
json["lng"].toDouble(),
);
Map<String, dynamic> toJson(LatLng coordinate) => {
"lat": coordinate.latitude,
"lng": coordinate.longitude,
};
这是存储库中的方法:
Future<List<UserRoute>> loadRoutes() async {
final db = await database;
var res = await db.query("Route");
List<UserRoute> list =
res.isNotEmpty ? res.map((c) => UserRoute.fromMap(c)).toList() : [];
return list;
}
这是屏幕:
class SelectRouteScreen extends StatefulWidget {
bool isIOS = Platform.isIOS ? true : false;
User user;
String routeName;
SelectRouteScreen({@required this.user});
@override
_SelectRouteScreenState createState() => _SelectRouteScreenState();
}
class _SelectRouteScreenState extends State<SelectRouteScreen> {
@override
Widget build(BuildContext context) {
AudioCache cache = new AudioCache();
List<UserRoute> routes = [];
List<RouteCell> cells = [];
cache.loadAll(['click.mp3', 'tableViewOpen.mp3', 'tableViewClose.mp3']);
return BlocListener<RouteBloc, RouteState>(
listener: (BuildContext context, RouteState state) {
if (state is RoutesLoaded) {
print('state received');
setState(() {
routes.clear();
cells.clear();
routes = state.userRoutes;
print('saved route are ${state.userRoutes.length}');
print(routes);
cells = state.schedulerCells;
});
}
},
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
centerTitle: true,
leading: IconButton(
icon: widget.isIOS
? Icon(CupertinoIcons.back)
: Icon(Icons.arrow_back),
color: Colors.redAccent,
onPressed: () {
cache.play('tableViewClose.mp3');
Navigator.pop(context, widget.routeName);
}),
title: Text(
'Seleziona tragitto',
style: TextStyle(
color: Colors.orange,
fontSize: 22,
fontWeight: FontWeight.w500,
letterSpacing: 1),
),
),
body: Container(
padding: EdgeInsets.all(20),
color: Colors.redAccent,
child: ListView.builder(
itemCount: routes.length,
// itemBuilder: (BuildContext context, int index) => Container(
// padding: EdgeInsets.all(10),
// color: Colors.red,
// child: cells[index],
// ),
itemBuilder: (BuildContext context, int index) => RouteCell(
routeName: '${routes[index].routeName}',
isSelected: false,
onTap: () {
widget.routeName = routes[index].routeName;
},
onTapCancel: () {
widget.routeName = null;
},
),
),
),
),
);
}
}
这是到屏幕的导航:
IconButton(
icon: isIOS
? Icon(CupertinoIcons.forward)
: Icon(Icons.arrow_forward),
iconSize: 20,
color: Colors.redAccent,
onPressed: () async {
cache.play('tableViewOpen.mp3');
Timer(Duration(milliseconds: 200), () {
BlocProvider.of<RouteBloc>(context).add(
LoadRoutes(userName: widget.user.name));
});
// routeName = await Navigator.push(
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => BlocProvider.value(
value:
BlocProvider.of<RouteBloc>(context),
child:
SelectRouteScreen(user: widget.user),
),
),
);
},
)
这似乎发生在使用模型结构的列表中,请尝试更改
final List<LatLng> coordinates;
to
final List<dynamic> coordinates;
和来自
List<LatLng> latLngFromJson(String str) {
final jsonData = json.decode(str);
return new List<LatLng>.from(jsonData.map((x) => fromJson(x)));
}
to
List<dynamic> latLngFromJson(String str) {
final jsonData = json.decode(str);
return new List<dynamic>.from(jsonData.map((x) => fromJson(x)));
}
在您的模型课程中。