我是新手,并尝试使用以下格式从API解析JSON数据:
[
{
"imageId": "5d30b60313fdf803e4db4500",
"imageName": "chair",
"imageUrl": "https://quotesst.blob.core.windows.net/myquotes/nature-4.jpg",
"quote": "chair is good"
},
{
"imageId": "5d8b1bcc1c9d4400000346f0",
"imageName": "quote1",
"imageUrl": "https://quotesst.blob.core.windows.net/myquotes/nature-4.jpg",
"quote": "\"Success is not final; failure is not fatal: It is the courage to continue that counts.\" Winston S. Churchill"
},
{
"imageId": "5d8b1c641c9d4400000346f1",
"imageName": "quote2",
"imageUrl": "https://quotesst.blob.core.windows.net/myquotes/nature-4.jpg",
"quote": "“It is better to fail in originality than to succeed in imitation.” Herman Melville"
}
]
和我的扑通类如下:
import 'dart:core';
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
const url =
'myapiurl';
class EnglishDatabase {
Map<int, Map<String, String>> data = new Map();
int dataLength = 0;
List<String> temp;
EnglishDatabase();
void getData() async {
Map<int, Map<String, String>> s;
try {
http.Response r = await http.get(url);
if (r.statusCode == 200) {
s = jsonDecode(r.body);
data.addAll(s);
dataLength = s.length;
}
} catch (e) {
print(e);
}
}
void returnQuotes() async {
await getData();
for (int i = 0; i < data.length; i++) {
temp.add(data[i]['quote']);
}
}
Iterable<String> getQuotes() {
returnQuotes();
return temp.reversed;
}
int getQuotesLength() {
return dataLength;
}
}
和我用来调用该类以显示数据的类如下:
import 'dart:core';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:quotes_flutter_stories/Database/EnglishQuoteData.dart';
import 'dart:async';
import 'Themes.dart';
import 'package:http/http.dart' as http;
import 'package:share/share.dart';
import 'main.dart';
//import 'package:quotes_flutter_stories/Database/EnglishQuoteData.dart';
EnglishDatabase _englishData;
class EnglishScreen extends StatefulWidget {
@override
_EnglishScreenState createState() => _EnglishScreenState();
}
class _EnglishScreenState extends State<EnglishScreen> {
Iterable<String> englishQuotes;
@override
void initState() {
englishQuotes = _englishData.getQuotes();
super.initState();
}
List<String> englishStories = [
'\"Try not to become a man of success. Rather become a man of value.\" \nAlbert Einstein',
'\"Successful people do what unsuccessful people are not willing to do. Don\'t wish it were easier; wish you were better.\" \nJim Rohn',
'\"I find that the harder I work; the more luck I seem to have.\" \nThomas Jefferson',
'\"Don\'t be afraid to give up the good to go for the great.\" \nJohn D. Rockefeller',
'\"Opportunities don\'t happen. You create them.\" \nChris Grosser',
'\"It is better to fail in originality than to succeed in imitation.\" \nHerman Melville',
];
Widget _buildRowQ(String englishQuote) {
return new ListTile(
leading: Container(
decoration: new BoxDecoration(
color: Colors.orangeAccent,
borderRadius: new BorderRadius.circular(4.0),
),
padding: new EdgeInsets.all(4.0),
height: 30.0,
width: 30.0,
child: new Text(
englishQuote.substring(1, 2),
textAlign: TextAlign.center,
),
),
title: new Text(englishQuote),
subtitle: new Divider(
height: 20.0,
color: Colors.black,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => QuotePage(englishQ: englishQuote)));
},
);
}
Widget _buildRowF(String englishFavourite) {
return new ListTile(
leading: Container(
decoration: new BoxDecoration(
color: Colors.orangeAccent,
borderRadius: new BorderRadius.circular(4.0),
),
padding: new EdgeInsets.all(4.0),
height: 30.0,
width: 30.0,
child: new Text(
englishFavourite.substring(1, 2),
textAlign: TextAlign.center,
),
),
title: new Text(englishFavourite),
subtitle: new Divider(
height: 20.0,
color: Colors.black,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
FavouritePage(englishF: englishFavourite)));
},
);
}
Widget _buildRowS(String englishQuote) {
return new ListTile(
leading: Container(
decoration: new BoxDecoration(
color: Colors.orangeAccent,
borderRadius: new BorderRadius.circular(4.0),
),
padding: new EdgeInsets.all(4.0),
height: 30.0,
width: 30.0,
child: new Text(
englishQuote.substring(1, 2),
textAlign: TextAlign.center,
),
),
title: new Text(englishQuote),
subtitle: new Divider(
height: 20.0,
color: Colors.black,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StoryPage(englishS: englishQuote)));
},
);
}
@override
Widget build(BuildContext context) {
final List<String> _menuitems = ["Change Language", "Rate US", "About Us"];
return MaterialApp(
theme: mainTheme,
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('Quotes & Stories'),
actions: <Widget>[
DropdownButton(
icon: Icon(Icons.menu),
items: _menuitems
.map((value) => DropdownMenuItem(
child: Text(value),
value: value,
))
.toList(),
onChanged: (String value) {
setState(() {
if (value == _menuitems[0]) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => LanguageSelection()));
} else if (value == _menuitems[1]) {
Navigator.push(context,
MaterialPageRoute(builder: (context) => RatePage()));
} else if (value == _menuitems[2]) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AboutUsPage()));
}
});
},
isExpanded: false,
),
SizedBox(
width: 20.0,
),
],
bottom: TabBar(
tabs: <Widget>[
Tab(
text: 'Quotes',
),
Tab(
text: 'Favourites',
),
Tab(
text: 'Stories',
),
],
),
),
body: TabBarView(
children: [
englishQuotes.isEmpty
? Center(
child: Text('No Quotes'),
)
: ListView.builder(
itemCount: _englishData.getQuotesLength(),
padding: const EdgeInsets.all(10.0),
itemBuilder: (context, i) {
return _buildRowQ(englishQuotes.elementAt(i));
},
),
favourites.isEmpty
? Center(
child: Text('No Favourites'),
)
: ListView.builder(
itemCount: favourites.length,
padding: EdgeInsets.all(10.0),
itemBuilder: (context, i) {
return _buildRowF(favourites[i]);
},
),
englishStories.isEmpty
? Center(
child: Text('No Stories'),
)
: ListView.builder(
itemCount: englishStories.length,
padding: EdgeInsets.all(10.0),
itemBuilder: (context, i) {
return _buildRowS(englishStories[i]);
},
),
],
),
),
),
);
}
}
class StoryPage extends StatefulWidget {
final String englishS;
StoryPage({Key key, @required this.englishS}) : super(key: key);
@override
_StoryPageState createState() => _StoryPageState();
}
class _StoryPageState extends State<StoryPage> {
@override
Widget build(BuildContext context) {
String englishStory = widget.englishS;
return MaterialApp(
theme: mainTheme,
home: Scaffold(
appBar: AppBar(
title: Center(child: Text('English Story')),
),
body: Center(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/1.jfif"),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(),
SizedBox(
height: 250.0,
),
Text(
englishStory,
textAlign: TextAlign.center,
),
SizedBox(
height: 185.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: favourites.contains(englishStory)
? Icon(Icons.favorite)
: Icon(Icons.favorite_border),
color:
favourites.contains(englishStory) ? Colors.red : null,
onPressed: () {
setState(() {
if (favourites.contains(englishStory))
favourites.remove(englishStory);
else
favourites.add(englishStory);
});
},
),
IconButton(
icon: Icon(Icons.share),
onPressed: () async {
await Share.share(englishStory);
},
)
],
),
SizedBox(
height: 15.0,
),
FlatButton(
child: Container(
width: double.infinity,
height: 40.0,
child: Center(
child: Text('Back'),
),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
),
),
);
}
}
class QuotePage extends StatefulWidget {
final String englishQ;
QuotePage({Key key, @required this.englishQ}) : super(key: key);
@override
_QuotePageState createState() => _QuotePageState();
}
class _QuotePageState extends State<QuotePage> {
@override
Widget build(BuildContext context) {
String englishQuote = widget.englishQ;
return MaterialApp(
theme: mainTheme,
home: Scaffold(
appBar: AppBar(
title: Center(child: Text('English Quote')),
),
body: Center(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/1.jfif"),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(),
SizedBox(
height: 250.0,
),
Text(
englishQuote,
textAlign: TextAlign.center,
),
SizedBox(
height: 185.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: favourites.contains(englishQuote)
? Icon(Icons.favorite)
: Icon(Icons.favorite_border),
color:
favourites.contains(englishQuote) ? Colors.red : null,
onPressed: () {
setState(() {
if (favourites.contains(englishQuote))
favourites.remove(englishQuote);
else
favourites.add(englishQuote);
});
},
),
IconButton(
icon: Icon(Icons.share),
onPressed: () async {
if (Platform.isAndroid) {
await Share.share(englishQuote);
}
},
)
],
),
SizedBox(
height: 15.0,
),
FlatButton(
child: Container(
width: double.infinity,
height: 40.0,
child: Center(
child: Text('Back'),
),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
),
),
);
}
}
class FavouritePage extends StatefulWidget {
final String englishF;
FavouritePage({Key key, @required this.englishF}) : super(key: key);
@override
_FavouritePageState createState() => _FavouritePageState();
}
class _FavouritePageState extends State<FavouritePage> {
@override
Widget build(BuildContext context) {
String englishFavourite = widget.englishF;
return MaterialApp(
theme: mainTheme,
home: Scaffold(
appBar: AppBar(
title: Center(child: Text('Favourite')),
),
body: Center(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/1.jfif"),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(),
SizedBox(
height: 250.0,
),
Text(
englishFavourite,
textAlign: TextAlign.center,
),
SizedBox(
height: 185.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: favourites.contains(englishFavourite)
? Icon(Icons.favorite)
: Icon(Icons.favorite_border),
color: favourites.contains(englishFavourite)
? Colors.red
: null,
onPressed: () {
setState(() {
if (favourites.contains(englishFavourite))
favourites.remove(englishFavourite);
else
favourites.add(englishFavourite);
});
},
),
IconButton(
icon: Icon(Icons.share),
onPressed: () async {
await Share.share(englishFavourite);
},
)
],
),
SizedBox(
height: 15.0,
),
FlatButton(
child: Container(
width: double.infinity,
height: 40.0,
child: Center(
child: Text('Back'),
),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
),
),
);
}
}
所以如果有人能帮助我,我将非常感谢。
注意:您可以忽略englishStories的一部分,因为它只是其他一些测试。谢谢。
答案 0 :(得分:0)
以下是示例Dart代码,可能会对您有所帮助。
class Dependent {
void getData() async {
print('reached');
}
}
void main() {
Dependent().getData();
}
答案 1 :(得分:0)
我的问题的答案是这样的: 如果您希望虚拟值可以固定增长,则必须在列表中放置一个虚拟值,否则该虚拟值将是固定的,并且您无法使用其方法添加值,因为它会崩溃。这是扑扑团队的文档:
具有长度的可索引对象集合。
此类的子类实现不同类型的列表。最常见的列表类型是:
固定长度列表。尝试使用可以更改列表长度的操作时发生错误。
可浏览列表。此类中定义的API的完整实现。
由新List()或[]返回的默认可增长列表保留一个内部缓冲区,并在必要时增长该缓冲区。这保证了一系列添加操作将在固定的固定时间内执行。直接设置长度可能要花费与新长度成比例的时间,并且可能会更改内部容量,因此随后的添加操作将需要立即增加缓冲区容量。其他列表实现可能具有不同的性能行为。
以下代码说明某些List实现仅支持API的一部分。
List<int> fixedLengthList = new List(5);
fixedLengthList.length = 0; // Error
fixedLengthList.add(499); // Error
fixedLengthList[0] = 87;
List<int> growableList = [1, 2];
growableList.length = 0;
growableList.add(499);
growableList[0] = 87;
列表是可迭代的。迭代发生在索引顺序的值上。更改值不会影响迭代,但是在迭代步骤之间更改有效索引(即更改列表的长度)会导致ConcurrentModificationError。这意味着只有可增长的列表才能引发ConcurrentModificationError。如果长度暂时改变并且在继续迭代之前已恢复,则迭代器不会检测到它。
在执行列表操作时,例如在调用forEach或sort期间,通常不允许修改列表的长度(添加或删除元素)。通过直接对其进行迭代或通过迭代由列表支持的Iterable来更改列表的长度,将会中断迭代。