【发布时间】:2021-01-21 05:48:24
【问题描述】:
所以我想映射以下 JSON。
{"data":[{"track":{"artist":"Other Ego","title":"Titanium (2Complex Remix)","imageurl":"https://storage.googleapis.com/ad-system/AdStichr-Logo.png","url":"https://www.adstichr.com/","type":"S"}}]}
但我只需要能够阅读
{"artist":"Other Ego","title":"Titanium (2Complex Remix)","imageurl":"https://storage.googleapis.com/ad-system/AdStichr-Logo.png","url":"https://www.adstichr.com/","type":"S"}}
通常我会这样做。
factory Photo.fromJson(Map<String, dynamic> json) => Photo(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
但是我需要这样做,而不是在其中包含 track。有没有做类似的事情
factory Photo.fromJson(Map<String, dynamic> json) => Photo(
data: List<Datum>.from(json["data"][0]["track"].map((x) => Datum.fromJson(x))),
);
如果不是,实现我想做的最简单的方法是什么?
我问的原因是我收到以下错误:
Error: The argument type 'List<Natum>' can't be assigned to the parameter type 'List<Datum>'.
- 'List' is from 'dart:core'.
- 'Natum' is from 'package:drn1/home_widget.dart' ('lib/home_widget.dart').
- 'Datum' is from 'package:drn1/home_widget.dart' ('lib/home_widget.dart').
data: List<Natum>.from(json["data.0.track"].map((x) => Natum.fromJson(x))),
^
lib/home_widget.dart:75:20: Error: The argument type 'Photo Function(String)' can't be assigned to the parameter type 'FutureOr<Nplaying> Function(String)'.
- 'Photo' is from 'package:drn1/home_widget.dart' ('lib/home_widget.dart').
- 'Nplaying' is from 'package:drn1/home_widget.dart' ('lib/home_widget.dart').
return compute(parseNowPlaying, response.body);
^
lib/home_widget.dart:84:10: Error: A value of type 'Nplaying' can't be assigned to a variable of type 'Photo'.
- 'Nplaying' is from 'package:drn1/home_widget.dart' ('lib/home_widget.dart').
- 'Photo' is from 'package:drn1/home_widget.dart' ('lib/home_widget.dart').
return nowplayingFromJSON(responseBody);
^
lib/home_widget.dart:367:23: Error: The argument type 'Future<Nplaying>' can't be assigned to the parameter type 'Future<Photo>'.
- 'Future' is from 'dart:async'.
- 'Nplaying' is from 'package:drn1/home_widget.dart' ('lib/home_widget.dart').
- 'Photo' is from 'package:drn1/home_widget.dart' ('lib/home_widget.dart').
future: fetchNowPlaying(http.Client()),
^
这是我添加到项目中的添加代码 - 请注意,我不能使用 Photo,因为我已经使用它来获取电台。
//GET NOW PLAYING INFO
Nplaying nowplayingFromJSON(String str) => Nplaying.fromJson(json.decode(str));
String nowplayingToJson(Nplaying data) => json.encode(data.toJson());
class Nplaying {
Nplaying({
this.data,
});
List<Datum> data;
factory Nplaying.fromJson(Map<String, dynamic> json) => Nplaying(
data: List<Natum>.from(json["data.0.track"].map((x) => Natum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Natum {
Natum({
this.artist,
this.title,
this.imageurl,
this.url,
this.type,
});
String artist;
String title;
String imageurl;
String url;
String type;
factory Natum.fromJson(Map<String, dynamic> json) => Natum(
artist: json["artist"],
title: json["title"],
imageurl: json["imageurl"],
url: json["url"],
type: json["type"],
);
Map<String, dynamic> toJson() => {
"artist": artist,
"title": title,
"imageurl": imageurl,
"url": url,
"type": type,
};
}
/* END NOWPLAYING JSON */
/* TO FETCH NowPlaying */
Future<Nplaying> fetchNowPlaying(http.Client client) async {
/* final response = await client.get('https://api.drn1.com.au/station/allstations');
// Use the compute function to run parsePhotos in a separate isolate.
*/
try {
final response = await client.get('https://api.drn1.com.au:9000/nowplaying/DRN1?uuid=3b9c4e7adf59b4fb');
return compute(parseNowPlaying, response.body);
} catch (e) {
print(e);
}
}
// A function that converts a response body into a List<Photo>.
Photo parseNowPlaying(String responseBody) {
return nowplayingFromJSON(responseBody);
}
class NowPhotosList extends StatelessWidget {
final Photo photos;
final uuid;
NowPhotosList({Key key, this.photos, this.uuid}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
// childAspectRatio: MediaQuery.of(context).size.width /
// (MediaQuery.of(context).size.height / 4), //childAspectRatio: 200,
),
scrollDirection: Axis.horizontal,
itemCount: photos.data.length,
itemBuilder: (context, index) {
return RaisedButton(
padding: const EdgeInsets.all(0),
textColor: Colors.white,
color: Colors.black,
onPressed: () async { print("hello");
},
child: CachedNetworkImage(
imageUrl: photos.data[index].imageurl,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
);
// return Image.network(photos.data[index].imageurl, width: 80.0, height: 80.0,);
},
);
}
}
这是完整的代码。
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/services.dart';
import 'package:platform_device_id/platform_device_id.dart';
import 'package:flutter_radio_player/flutter_radio_player.dart';
import './screens/trackswidget.dart';
import 'about_widget.dart';
//GET NOW PLAYING INFO
Nplaying nowplayingFromJSON(String str) => Nplaying.fromJson(json.decode(str));
String nowplayingToJson(Nplaying data) => json.encode(data.toJson());
class Nplaying {
Nplaying({
this.data,
});
List<Datum> data;
factory Nplaying.fromJson(Map<String, dynamic> json) => Nplaying(
data: List<Natum>.from(json["data.0.track"].map((x) => Natum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Natum {
Natum({
this.artist,
this.title,
this.imageurl,
this.url,
this.type,
});
String artist;
String title;
String imageurl;
String url;
String type;
factory Natum.fromJson(Map<String, dynamic> json) => Natum(
artist: json["artist"],
title: json["title"],
imageurl: json["imageurl"],
url: json["url"],
type: json["type"],
);
Map<String, dynamic> toJson() => {
"artist": artist,
"title": title,
"imageurl": imageurl,
"url": url,
"type": type,
};
}
/* END NOWPLAYING JSON */
/* TO FETCH NowPlaying */
Future<Nplaying> fetchNowPlaying(http.Client client) async {
/* final response = await client.get('https://api.drn1.com.au/station/allstations');
// Use the compute function to run parsePhotos in a separate isolate.
*/
try {
final response = await client.get('https://api.drn1.com.au:9000/nowplaying/DRN1?uuid=3b9c4e7adf59b4fb');
return compute(parseNowPlaying, response.body);
} catch (e) {
print(e);
}
}
// A function that converts a response body into a List<Photo>.
Photo parseNowPlaying(String responseBody) {
return nowplayingFromJSON(responseBody);
}
class NowPhotosList extends StatelessWidget {
final Photo photos;
final uuid;
NowPhotosList({Key key, this.photos, this.uuid}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
// childAspectRatio: MediaQuery.of(context).size.width /
// (MediaQuery.of(context).size.height / 4), //childAspectRatio: 200,
),
scrollDirection: Axis.horizontal,
itemCount: photos.data.length,
itemBuilder: (context, index) {
return RaisedButton(
padding: const EdgeInsets.all(0),
textColor: Colors.white,
color: Colors.black,
onPressed: () async { print("hello");
},
child: CachedNetworkImage(
imageUrl: photos.data[index].imageurl,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
);
// return Image.network(photos.data[index].imageurl, width: 80.0, height: 80.0,);
},
);
}
}
//GET STATIONS
/* TO FETCH PHOTOS */
Photo photoFromJson(String str) => Photo.fromJson(json.decode(str));
String photoToJson(Photo data) => json.encode(data.toJson());
class Photo {
Photo({
this.data,
});
List<Datum> data;
factory Photo.fromJson(Map<String, dynamic> json) => Photo(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
/*START OF STATIONS JSON*/
class Datum {
Datum({
this.id,
this.name,
this.imageurl,
this.website,
this.listenlive,
});
String id;
String name;
String imageurl;
String website;
String listenlive;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["_id"],
name: json["name"],
imageurl: json["imageurl"],
website: json["website"],
listenlive: json["listenlive"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"name": name,
"imageurl": imageurl,
"website": website,
"listenlive": listenlive,
};
}
/*END OF STATIONS JSON*/
/* TO FETCH PHOTOS */
Future<Photo> fetchPhotos(http.Client client) async {
/* final response = await client.get('https://api.drn1.com.au/station/allstations');
// Use the compute function to run parsePhotos in a separate isolate.
*/
try {
final response = await client.get('https://api.drn1.com.au/station/allstations');
return compute(parsePhotos, response.body);
} catch (e) {
print(e);
}
}
// A function that converts a response body into a List<Photo>.
Photo parsePhotos(String responseBody) {
return photoFromJson(responseBody);
}
class PhotosList extends StatelessWidget {
final Photo photos;
final uuid;
FlutterRadioPlayer _flutterRadioPlayer = new FlutterRadioPlayer();
PhotosList({Key key, this.photos, this.uuid}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
// childAspectRatio: MediaQuery.of(context).size.width /
// (MediaQuery.of(context).size.height / 4), //childAspectRatio: 200,
),
scrollDirection: Axis.horizontal,
itemCount: photos.data.length,
itemBuilder: (context, index) {
return RaisedButton(
padding: const EdgeInsets.all(0),
textColor: Colors.white,
color: Colors.black,
onPressed: () async { await _flutterRadioPlayer.setUrl(photos.data[index].listenlive+'?uuid='+uuid, "true");
},
child: CachedNetworkImage(
imageUrl: photos.data[index].imageurl,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
);
// return Image.network(photos.data[index].imageurl, width: 80.0, height: 80.0,);
},
);
}
}
/*END FETCH PHOTOS*/
class Home extends StatefulWidget {
var playerState = FlutterRadioPlayer.flutter_radio_paused;
var volume = 0.8;
@override
State<StatefulWidget> createState() {
return _HomeState();
}
}
class _HomeState extends State<Home> {
String _deviceId = 'Unknown';
/* Future<Radata> _future;
Future<Radata> getHttp() async {
http.Response response =
await http.get("https://api.drn1.com.au/station/allstations");
if (response.statusCode == 200) {
return radataFromJson(response.body);
}
}
*/
bool check = true;
int _currentIndex = 0;
FlutterRadioPlayer _flutterRadioPlayer = new FlutterRadioPlayer();
@override
void initState() {
// _future = getHttp();
initPlatformState();
initRadioService();
super.initState();
}
Future<void> initPlatformState() async {
String deviceId;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
deviceId = await PlatformDeviceId.getDeviceId;
} on PlatformException {
deviceId = 'Failed to get deviceId.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_deviceId = deviceId;
print("deviceId->$_deviceId");
});
}
Future<void> initRadioService() async {
try {
await _flutterRadioPlayer.init(
"DRN1", "Live", "http://stream.radiomedia.com.au:8003/stream", "true");
} on PlatformException {
print("Exception occurred while trying to register the services.");
}
//await _flutterRadioPlayer.play();
}
Future<void> changestation(e) async{
try {
await _flutterRadioPlayer.setUrl(e, "true");
// await _flutterRadioPlayer.play();
} on PlatformException {
print("Exception occurred while trying to register the services.");
}
}
final List<Widget> _children = [TracksWidget(),
AboutWidget()];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('DRN',style: TextStyle(color: Colors.white, fontSize: 40.0),),
const Text('1', style: TextStyle(color: Colors.red, fontSize: 40.0),)
],
),
),
//body: _children[_currentIndex],
body: Column(children: [
// Now Playing Information
SizedBox(
width: double.infinity,
height:200,
child: Container(
color: Colors.red,
child:
FutureBuilder<Photo>(
future: fetchNowPlaying(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? Container(child: NowPhotosList(photos: snapshot.data,uuid:_deviceId))
: Center(child: CircularProgressIndicator());
},
),
),
),
// END NOW PLAYING INFORMATION
SizedBox(
width: double.infinity,
height:40,
child: Container(
color: Colors.white,
child: Text(
"Our Stations",
textAlign: TextAlign.left,
textScaleFactor: 2,
),
),
),
//START STATIONS
SizedBox(
width: double.infinity,
height:200,
child: Container(
color: Colors.red,
child:
FutureBuilder<Photo>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? Container(child: PhotosList(photos: snapshot.data,uuid:_deviceId))
: Center(child: CircularProgressIndicator());
},
),
),
),
//END STATIONS
SizedBox(
width: double.infinity,
//height:40,
child: Container(
color: Colors.white,
child: Text(
"\n\nTo all our valued Android Listeners.\n\nWe are working on making our android app better for all, updates will be out over the coming months.\n\nClick on any station icon to tune into the station. If the station does not start playing at time of launching the app, please reboot the app.",
textAlign: TextAlign.left,
textScaleFactor: 1,
),
),
),
]),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 80.0,
width: 80.0,
child: FittedBox(
child:FloatingActionButton(
onPressed: () => {
setState((){
if(check)
{
check = false;
_flutterRadioPlayer.play();
print("false");
}
else
{
check = true;
_flutterRadioPlayer.pause();
print("true");
}
}),
},
child: Icon(check ? Icons.play_arrow: Icons.pause),
backgroundColor: Colors.black,
mini: true,
),
),
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
child: Container(
decoration:
new BoxDecoration(color: new Color(0xFFFF0000)),
height: 75,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
/* IconButton(
iconSize: 30.0,
padding: EdgeInsets.only(left: 28.0),
icon: Icon(Icons.home),
onPressed: () {
setState(() {
onTabTapped(0);
});
},
),*/
/* IconButton(
iconSize: 30.0,
padding: EdgeInsets.only(right: 28.0),
icon: Icon(Icons.search),
onPressed: () {
setState(() {
onTabTapped(1);
});
},
),
IconButton(
iconSize: 30.0,
padding: EdgeInsets.only(left: 28.0),
icon: Icon(Icons.notifications),
onPressed: () {
setState(() {
onTabTapped(2);
});
},
),*/
/* IconButton(
iconSize: 30.0,
padding: EdgeInsets.only(right: 28.0),
icon: Icon(Icons.info_outline),
onPressed: () {
setState(() {
onTabTapped(1);
});
},
)*/
],
),
),
),// new
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
}
【问题讨论】: