So In Swift I do this:
struct Sdata: Codable {
var data: [Station]
}
struct Station: Codable , Identifiable {
var id,name,imageurl,listenlive:String
private enum CodingKeys : String, CodingKey {
case id = "_id", name , imageurl , listenlive
}
}
But I am wondering in flutter how is this structured?
As the example:
class Photo {
final int albumId;
final int id;
final String title;
final String url;
final String thumbnailUrl;
Photo({this.albumId, this.id, this.title, this.url, this.thumbnailUrl});
factory Photo.fromJson(Map<String, dynamic> json) {
return Photo(
albumId: json['albumId'] as int,
id: json['id'] as int,
title: json['title'] as String,
url: json['url'] as String,
thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
is not really helpful as it does not do a sub-array.
I have tried:
class Radata{
Source data;
Radata(
{
this.data
}
);
factory Radata.fromJson(Map<String, dynamic> json) {
return Radata(
data: Radio.fromJson(json["data"])
);
}
}
class Radio {
String id;
String name;
String imageurl;
Radio({this.id, this.name, this.imageurl});
factory Radio.fromJson(Map<String, dynamic> json) {
return Radio(
id: json["_id"] as String,
name: json["name"] as String,
imageurl: json["imageurl"] as String,
);
}
}
But get Error: 'Source' isn't a type.
It's for this url https://api.drn1.com.au/station/allstations
I tried the code below - as I need to intergrate it into my current app.
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:flutter_radio_player/flutter_radio_player.dart';
import './screens/trackswidget.dart';
import 'about_widget.dart';
import './model/photos.dart';
/* TO FETCH PHOTOS */
Future<List<Photo>> fetchPhotos(http.Client client) async {
final response =
//await client.get('https://jsonplaceholder.typicode.com/photos');
await client.get('https://api.drn1.com.au/station/allstations');
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parsePhotos, response.body);
}
// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
class PhotosList extends StatelessWidget {
final List<Photo> photos;
PhotosList({Key key, this.photos}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
),
scrollDirection: Axis.horizontal,
itemCount: photos.length,
itemBuilder: (context, index) {
return Image.network(photos[index].thumbnailUrl);
},
);
}
}
/*END FETCH PHOTOS*/
class Radata {
Radata({
this.data,
});
List<Radio> data;
factory Radata.fromJson(Map<String, dynamic> json) => Radata(
data: List<Radio>.from(json["data"].map((x) => Radio.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Radio {
Radio({
this.id,
this.name,
this.imageurl,
this.website,
this.listenlive,
});
String id;
String name;
String imageurl;
String website;
String listenlive;
factory Radio.fromJson(Map<String, dynamic> json) => Radio(
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,
};
}
Radata radataFromJson(String str) => Radata.fromJson(json.decode(str));
String radataToJson(Radata data) => json.encode(data.toJson());
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> {
bool check = true;
int _currentIndex = 0;
FlutterRadioPlayer _flutterRadioPlayer = new FlutterRadioPlayer();
@override
void initState() {
_future = getHttp();
super.initState();
initRadioService();
}
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.");
}
}
/* RADIO STATIONS */
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);
}
}
/* end radio stations */
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: [ SizedBox(
height:200,
child:ListView(
// This next line does the trick.
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 200.0,
height: 200.0,
color: Colors.red,
child: new RaisedButton(
padding: const EdgeInsets.all(0),
textColor: Colors.white,
color: Colors.red,
onPressed: () async { await changestation('http://stream.radiomedia.com.au:8006/stream');
},
child: CachedNetworkImage(
imageUrl: "http://via.placeholder.com/200x200",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
),
GestureDetector(
child: SizedBox(
width: 200,
height:200,
child: CachedNetworkImage(
imageUrl: "http://via.placeholder.com/200x200",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
onTap:() async { await changestation('http://stream.radiomedia.com.au:8015/stream');}
),
/*child: new RaisedButton(
padding: const EdgeInsets.all(0),
textColor: Colors.white,
color: Colors.blue,
onPressed: () async { await changestation('http://stream.radiomedia.com.au:8015/stream');
},
child: CachedNetworkImage(
imageUrl: "http://via.placeholder.com/200x200",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
*/
Container(
width: 200.0,
height: 200.0,
color: Colors.green,
),
Container(
width: 200.0,
height: 200.0,
color: Colors.yellow,
),
Container(
width: 200.0,
height: 200.0,
color: Colors.orange,
),
],
),
),
Expanded(
child: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<Radata> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (context, index) {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0,
bottom: 6.0,
left: 8.0,
right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(snapshot.data.data[index].name
.toString()),
Spacer(),
Text(
snapshot.data.data[index].id,
),
],
),
));
});
}
}
}),
),
Row(
children: <Widget>[
Expanded(
child: new RaisedButton(
padding: const EdgeInsets.all(8.0),
textColor: Colors.white,
color: Colors.blue,
onPressed: () async { await changestation('http://stream.radiomedia.com.au:8015/stream');
},
child: new Text("Change Station"),
),
),
Expanded(
child: Text('Craft beautiful UIs', textAlign: TextAlign.center),
),
Expanded(
child: FittedBox(
fit: BoxFit.contain, // otherwise the logo will be tiny
child: const FlutterLogo(),
),
),
],
),
]),
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;
});
}
}
and I keep getting none printing out.
You can copy paste run full code below
You can use Radata radataFromJson(String str) => Radata.fromJson(json.decode(str));
You can see full code for class Radata
and class Radio
code snippet
Radata radataFromJson(String str) => Radata.fromJson(json.decode(str));
...
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);
}
}
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
// To parse this JSON data, do
//
// final radata = radataFromJson(jsonString);
import 'dart:convert';
Radata radataFromJson(String str) => Radata.fromJson(json.decode(str));
String radataToJson(Radata data) => json.encode(data.toJson());
class Radata {
Radata({
this.data,
});
List<Radio> data;
factory Radata.fromJson(Map<String, dynamic> json) => Radata(
data: List<Radio>.from(json["data"].map((x) => Radio.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Radio {
Radio({
this.id,
this.name,
this.imageurl,
this.website,
this.listenlive,
});
String id;
String name;
String imageurl;
String website;
String listenlive;
factory Radio.fromJson(Map<String, dynamic> json) => Radio(
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,
};
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
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);
}
}
@override
void initState() {
_future = getHttp();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<Radata> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (context, index) {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0,
bottom: 6.0,
left: 8.0,
right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(snapshot.data.data[index].name
.toString()),
Spacer(),
Text(
snapshot.data.data[index].id,
),
],
),
));
});
}
}
}));
}
}
full code 2
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/services.dart';
import 'package:flutter_radio_player/flutter_radio_player.dart';
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())),
};
}
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,
};
}
/* TO FETCH PHOTOS */
Future<Photo> fetchPhotos(http.Client client) async {
final response =
//await client.get('https://jsonplaceholder.typicode.com/photos');
await client.get('https://api.drn1.com.au/station/allstations');
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parsePhotos, response.body);
}
// 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;
PhotosList({Key key, this.photos}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
),
scrollDirection: Axis.horizontal,
itemCount: photos.data.length,
itemBuilder: (context, index) {
return Image.network(photos.data[index].imageurl);
},
);
}
}
/*END FETCH PHOTOS*/
/* RADIO STATIONS */
Radata radataFromJson(String str) => Radata.fromJson(json.decode(str));
String radataToJson(Radata data) => json.encode(data.toJson());
class Radata {
Radata({
this.data,
});
List<Radio> data;
factory Radata.fromJson(Map<String, dynamic> json) => Radata(
data: List<Radio>.from(json["data"].map((x) => Radio.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Radio {
Radio({
this.id,
this.name,
this.imageurl,
this.website,
this.listenlive,
});
String id;
String name;
String imageurl;
String website;
String listenlive;
factory Radio.fromJson(Map<String, dynamic> json) => Radio(
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 RADIO STATIONS*/
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> {
bool check = true;
int _currentIndex = 0;
FlutterRadioPlayer _flutterRadioPlayer = FlutterRadioPlayer();
@override
void initState() {
super.initState();
//initRadioService();
}
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 = [
Text("TracksWidget()"),
Text("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: [
FutureBuilder<Photo>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? Expanded(child: PhotosList(photos: snapshot.data))
: Center(child: CircularProgressIndicator());
},
),
]),
/* body: Center(
child: Column(
children: <Widget>[
StreamBuilder(
stream: _flutterRadioPlayer.isPlayingStream,
initialData: widget.playerState,
builder:
(BuildContext context, AsyncSnapshot<String> snapshot) {
String returnData = snapshot.data;
print("object data: " + returnData);
switch (returnData) {
case FlutterRadioPlayer.flutter_radio_stopped:
return RaisedButton(
child: Text("Start listening now"),
onPressed: () async {
await initRadioService();
});
break;
case FlutterRadioPlayer.flutter_radio_loading:
return Text("Loading stream...");
case FlutterRadioPlayer.flutter_radio_error:
return RaisedButton(
child: Text("Retry ?"),
onPressed: () async {
await initRadioService();
});
break;
default:
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton(
onPressed: () async {
print("button press data: " +
snapshot.data.toString());
await _flutterRadioPlayer.playOrPause();
},
icon: snapshot.data ==
FlutterRadioPlayer
.flutter_radio_playing
? Icon(Icons.pause)
: Icon(Icons.play_arrow)),
IconButton(
onPressed: () async {
await _flutterRadioPlayer.stop();
},
icon: Icon(Icons.stop))
]);
break;
}
}),
Slider(
value: widget.volume,
min: 0,
max: 1.0,
onChanged: (value) => setState(() {
widget.volume = value;
_flutterRadioPlayer.setVolume(widget.volume);
})),
Text("Volume: " + (widget.volume * 100).toStringAsFixed(0))
],
),
),
*/
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: BoxDecoration(color: 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);
});
},
)
],
),
),
), //
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Home(),
);
}
}
working demo 2
User contributions licensed under CC BY-SA 3.0