![](/img/trans.png)
[英]Flutter: Display an array of strings from JSON in Futurebuilder containing a Listview
[英]Flutter display json array in listview
你好,我是 flutter 的新手
我正在创建一个新闻应用程序,我正在尝试从 json url 检索数据并在列表视图中打印。
我尝试通过 http 调用,但我不知道为什么会出现格式异常错误。
提前致谢!
我想在 listview 中打印 json 数据,但出现以下错误。
I/flutter ( 6077): https://janmabhoominewspapers.com/json.aspx?siteId=8&pDate=21012021
I/flutter ( 6077): "323411" : [{"title" "રસીકરણ મહાઅભિયાનનો શુભારંભ"},{"image" "https//www.janmabhoominewspapers.com/x-admin/PostedImages/43778b6b-ea74-45c0-9600-0ba72c1a618b_670x400.jpg"},{"description" "કોરોના યોદ્ધાઓ અને વિજ્ઞાનીઓનો આભાર મહામારી સામેના જંગમાં જીવની આહુતિ આપનારા આરોગ્યકર્મીઓને યાદ કરતા વડા પ્રધાન ભાવુક બન્યા નવી દિલ્હી, તા. 16 વૈશ્વિક મહામારી કોરોના સામે નિર્ણાયક જંગરૂપે ભારતમાં શનિવારે વિશ્વના સૌથી મોટા રસીકરણ અભિયાનના પ્રારંભ પ્રસંગે ભારે ભાવુક બની ગયેલા વડાપ્રધાન નરેન્દ�
I/flutter ( 6077): runZonedGuarded: Caught error in my root zone.
I/flutter ( 6077): ----------------FIREBASE CRASHLYTICS----------------
I/flutter ( 6077): FormatException: Unexpected character (at character 12)
I/flutter ( 6077): "323411" : [{"title" "રસીકરણ મહાઅભિયાનનો શુભારંભ"},{"image" "https//www.j...
I/flutter ( 6077): ^
I/flutter ( 6077):
I/flutter ( 6077): #0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1404:5)
I/flutter ( 6077): #1 _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:862:48)
I/flutter ( 6077): #2 _parseJson (dart:convert-patch/convert_patch.dart:40:10)
I/flutter ( 6077): #3 JsonDecoder.convert (dart:convert/json.dart:505:36)
I/flutter ( 6077): #4 JsonCodec.decode (dart:convert/json.dart:156:41)
I/flutter ( 6077): #5 _nationalNews.loadYourData (package:janmabhoomi/app_screens/fragment_pravasi_topheadlines.dart:98:29)
I/flutter ( 6077): <asynchronous suspension>
I/flutter ( 6077): #6 _nationalNews.initState (package:janmabhoomi/app_screens/fragment_pravasi_topheadlines.dart:121:5)
I/flutter ( 6077): #7 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4702:58)
I/flutter ( 6077): #8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4538:5)
I/flutter ( 6077): #9 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)
I/flutter ( 6077): #10 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)
I/flutter ( 6077): #11 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4589:16)
I/flutter ( 6077): #12 E
下面是我试图在列表视图中打印的 json 数据
{ "323411" : [{"title" : "રસીકરણ મહાઅભિયાનનો શુભારંભ"},{"image" : "https://www.janmabhoominewspapers.com/x-admin/PostedImages/43778b6b-ea74-45c0-9600-0ba72c1a618b_670x400.jpg"},{"description" : "કોરોના યોદ્ધાઓ અને વિજ્ઞાનીઓનો આભાર
મહામારી સામેના જંગમાં જીવની આહુતિ આપનારા
આરોગ્યકર્મીઓને યાદ કરતા વડા પ્રધાન ભાવુક બન્યા
નવી દિલ્હી, તા. 16 : વૈશ્વિક મહામારી કોરોના સામે નિર્ણાયક જંગરૂપે ભારતમાં શનિવારે વિશ્વના સૌથી મોટા રસીકરણ અભિયાનના પ્રારંભ પ્રસંગે ભારે ભાવુક બની ગયેલા વડાપ્રધાન નરેન્દ્ર મોદીએ વીડિયો કોન્ફરન્સિંગથી દેશને સંબોધન કર્યું હતું. આરોગ્ય સંકટના શરૂઆતના દિવસોના સંઘર્ષને યાદ કરતાં મોદીની આંખોમાં આંસુ આવી ગયાં હતાં.
સેંકડો સાથીઓ એવા પણ છે, જે કદી પોતાના ઘરે પાછા ન ફર્યા. એક-એક જીવન બચાવવા માટે તેમણે પોતાના જીવનની આહુતિ આપી દીધી. સૌથી પ્રથમ રસી આવા આરોગ્યકર્મીઓને આપી, સમાજ ઋણ ચૂકવી રહ્યો છે, તેવું બોલતા વડાપ્રધાનની આંખો ભીની થઈ ગઈ હતી.
આરોગ્યકર્મીઓ, રસી માટે દેશના વૈજ્ઞાનિકો તેમજ કોરોના યોદ્ધાઓનો આભાર માનતા મોદીએ દેશવાસીઓને રસી અંગે કોઈ પણ પ્રકારની અફવાઓથી બચવાની અપીલ કરી હતી.
રસીનો બીજો ડોઝ લીધા પછી જ રોગપ્રતિકારક શક્તિ વિકસી શકે છે, એ ધ્યાને લેતાં પહેલો ડોઝ લઈ લીધા બાદ માસ્ક ઉતારી નાખવાની ભૂલ ન કરવાની અપીલ પણ તેમણે કરી હતી.
દુનિયાના 100થી વધુ એવા દેશ છે, જેમની કુલ વસતી પણ 3 કરોડથી ઓછી છે, ત્યારે ભારત દેશ માત્ર પહેલાં ચરણમાં ત્રણ કરોડ લોકોને રસી લગાવી રહ્યો છે તેવું વડાપ્રધાને કહ્યું હતું.
મોદીએ જણાવ્યું હતું કે, જનતા કર્ફ્યુ કોરોના સામે લડાઈમાં ભારતના સમાજના સંયમ અને શિસ્તની કસોટી હતી.
જનતા કર્ફ્યુએ જ દેશને લોકડાઉન માટે મનોવૈજ્ઞાનિકરૂપે તૈયાર કર્યો. તાળી-થાળી વગાડીને દીવા પ્રગટાવીને આપણે દેશનો આત્મવિશ્વાસ ઊંચો રાખ્યો તેવું તેમણે ઉમેર્યું હતું."}] ,"323410" : [{"title" : "પ્રથમ દિવસે ત્રણ લાખ લોકોને રસી અપાઈ"},{"image" : "https://www.janmabhoominewspapers.com/x-admin/PostedImages/0bdd1e84-fe8e-4b21-8f36-2ddcfe6c2903_670x400.jpg"},{"description" : "ભારત બાયોટેકે દુષ્પરિણામ બદલ વળતરની સ્પષ્ટતા કરી
નવી દિલ્હી, તા. 16 : ભારતમાં દુનિયાનું સૌથી મોટુ રસીકરણ અભિયાન શરૂ થઈ ચુક્યું છે. વર્તમાન યોજનામાં 3 કરોડ લોકોને પ્રાથમિકતાના આધારે રસી આપવામાં આવી રહી છે. રસીકરણના પહેલા દિવસે 3 લાખથી વધારે સ્વાસ્થ્ય કર્મીઓને રસી આપવામાં આવી હતી. વડાપ્રધાન નરેન્દ્ર મોદી અભિયાનની શરૂઆત કરાવતા 3006 રસીકરણ કેન્દ્ર સાથે વર્ચ્યુઅલી જોડાયા હતા. દરેક જગ્યાએ લગભગ 100 લાભાર્થીને રસી આપવામાં આવી હતી.'' આ દરમિયાન ભારત બાયોટેકની રસી કોવેક્સિનને લઈને સતત સવાલો ઉઠી રહ્યા છે. તેવામાં કંપનીએ સ્પષ્ટ કર્યું છે કે કોઈપણ દુષ્પરિણામ જોવા મળશે તો લાભાર્થીને વળતર આપવામાં આવશે.''
હ ભારતમાં સીરમ' ઈન્સ્ટિટયૂટ દ્વારા વિકસિત કરવામાં આવેલી કોવિશીલ્ડ અને ભારત બાયોટેકની કોવેક્સિનને મંજૂરી આપવામાં આવી છે. જેને પહેલા જ રાજ્યો અને કેન્દ્ર શાસિત પ્રદેશોમાં પહોંચાડી દેવામાં આવી હતી. કોવિશીલ્ડ અને કોવેક્સિનના એક ડોઝની કીંમત ભારતમાં 200થી 295 રૂપિયા સુધી રહી શકે છે.'
હ સ્વાસ્થ્ય્ય મંત્રાલયે રસી બાદના દુષ્પ્રભાવો અંગે ચેતવણી આપી હતી. કોવિશીલ્ડના મામલામાં દુ:ખાવો, માથામાં દુ:ખાવો, થાક, પાઈરેક્સિયા, ઠંડી લાગવી આથ્રાલ્જિયા સહિતના હળવા પ્રભાવ મળી શકે છે. જ્યારે કોવેક્સિનના મામલામાં માથાનો દુ:ખાવા, થાક, તાવ, શરીરમાં દુ:ખાવો, પેટમાં દુ:ખાવો, ચક્કર આવવા વગેરે પ્રભાવ જોવા મળી શકે છે.'
હ તમામ રાજ્યો અને કેન્દ્ર શાસિત પ્રદેશોમાં લખેલા પત્રમાં સ્વાસ્થ્ય મંત્રાલયે કહ્યું હતું કે, કોરોના વાયરસની રસી માત્ર 18 વર્ષ કે તેથી ઉપરના માટે ઈમર્જન્સી ઉપયોગમાં જ આપવાની મંજૂરી છે. બીજો ડોઝ પણ પહેલા ડોઝમાં આપેલી જ રસી હોવી જોઈએ તેમ પણ કહેવામાં આવ્યું હતું.'
હ સ્વાસ્થ્ય કર્મીઓને સૌથી પહેલા રસી મળશે કારણ કે તેઓને સંક્રમણનું જોખમ વધારે છે. ત્યારબાદ ફ્રન્ટલાઈન વર્કર્સનું રસીકરણ થશે. અંતે 50 વર્ષથી વધુ ઉમરના વ્યક્તિઓને રસી આપવામાં આવશે.
હ કો-વિન એક ઓનલાઈન પ્લેટફોર્મ છે જેને કોવિડ-19 રસી વિતરણની દેખરેખ માટે બનાવવામાં આવી છે. સ્વાસ્થ્ય મંત્રાલયના કહેવા પ્રમાણે એન્ટી કોરોનાવાયરસ રસીનો પાયો તૈયાર થશે. એપ લોકો રસીકરણ પ્રક્રિયામાં પોતાને રજીસ્ટર કરવા સક્ષમ બને તે માટે પણ ડિઝાઈન કરવામાં આવી છે.'
હ અહેવાલ અનુસારસી મેળવાનારા વ્યક્તિને એક ફેકટ શીટ અને ખરાબ પરિણામ સંબંધિત ફોર્મ આપવામાં આવશે. જે ફોર્મમાં લાભાર્થીને શરૂઆતી 7 દિવસમાં સામે આવતા લક્ષણો લખવાના રહેશે."}]}
下面是我试图在 listview 中打印的代码
class JanmabhoomiPravasi_TH extends StatefulWidget {
int index;
String url;
String value_image,value_description,value_title;
JanmabhoomiPravasi_TH({Key key,this.value_image,this.value_description,this.value_title,this.index,this.url}) : super(key:key);
@override
_nationalNews createState() => _nationalNews();
}
class _nationalNews extends State<JanmabhoomiPravasi_TH> with AutomaticKeepAliveClientMixin<JanmabhoomiPravasi_TH> {
List<News> dataList = List();
GlobalKey<ScaffoldState> scaffoldState = GlobalKey();
AdmobBannerSize bannerSize;
bool _isLoading = false;
int o;
BuildContext context1;
List<String> newsIDs = List();
DateTime findLastDateOfTheWeek(DateTime dateTime) {
return dateTime.add(Duration(days: DateTime.daysPerWeek - dateTime.weekday));
}
DateTime findLastDateOfPreviousWeek(DateTime dateTime) {
final DateTime sameWeekDayOfLastWeek =
dateTime.subtract(const Duration(days: 7));
return findLastDateOfTheWeek(sameWeekDayOfLastWeek);
}
Future<String> loadFromAssets() async {
DateTime oops = DateTime.now();
o = DateTime.sunday;
String d_date = DateFormat('ddMMyyyy').format(oops);
var url;
DateTime p = oops.subtract(Duration(days: 1));
String previous_date = DateFormat('ddMMyyyy').format(p);
print(previous_date);
var response1 = await http
.get('https://janmabhoominewspapers.com/json.aspx?siteId=8&pDate='+ d_date,
headers: {"charset": "utf-8", "Accept-Charset": "utf-8"});
if (widget.url == null && response1.statusCode == 200){
url = 'https://janmabhoominewspapers.com/json.aspx?siteId=8&pDate='+ d_date;
}else if(widget.url != null) {
url = 'https://janmabhoominewspapers.com/json.aspx?siteId=8&pDate='+ widget.url;
}else if(response1.statusCode != 200 && widget.url == null){
url = 'https://janmabhoominewspapers.com/json.aspx?siteId=8&pDate='+ previous_date;
}
print(url);
var response = await http
.get(url, headers: {"charset": "utf-8", "Accept-Charset": "utf-8"});
String utfDecode = utf8.decode(response.bodyBytes);
//final validCharacters = RegExp(r'^[a-zA-Z0-9_\-=@,\n.;]+$,');
return utfDecode.replaceAll('<br />', '').replaceAll('\r', '').replaceAll('\n', '').replaceAll('\t', '');
}
Future loadYourData() async {
setState(() {
_isLoading = true;
});
String jsonString = await loadFromAssets();
String newStr = jsonString.substring(1, jsonString.length - 1);
print(newStr);
Map newStringMap = json.decode(newStr);
var list = new List();
newStringMap.forEach((key, value) {
list.add(value);
newsIDs.add(key.toString());
});
for (var newsList in list) {
var news = News.fromJson(newsList);
dataList.add(news);
}
print('This is the length' + dataList.length.toString());
print(dataList[0].title);
print(newsIDs[0]);
setState(() {
_isLoading = false;
});
}
@override
void initState() {
super.initState();
bannerSize = AdmobBannerSize.BANNER;
loadYourData();
String previous = DateFormat('ddMMyyyy').format(findLastDateOfTheWeek(DateTime.now()));
String previous_week = DateFormat('ddMMyyyy').format(findLastDateOfPreviousWeek(DateTime.now()));
print(previous);
print(previous_week);
}
_onShare(BuildContext context) {
final RenderBox box = context.findRenderObject();
Share.share('Get Latest News On Kutchmitra App (Download Now): \n https://play.google.com/store/apps/details?id=com.webpioneer.kutchmitra',
//subject: subject,
sharePositionOrigin:
box.localToGlobal(Offset.zero) &
box.size);
}
@override
Widget build(BuildContext context) {
DateTime oops = DateTime.now();
return Container(
child: Container(
child: _isLoading
? Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
//scrollDirection: Axis.horizontal,
itemCount: dataList.length,
itemBuilder: (context, index) {
if (dataList[index].image.isEmpty){
if (index != 0 && index % 5 == 0) {
return Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 20.0),
child:
AdmobBanner(
adUnitId: getBannerAdUnitId(),
adSize: bannerSize,
),
),
],
);
}
return SizedBox(
height: 180,
width: MediaQuery.of(context).size.width,
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
print(index);
return Newsdetail(
value_image: dataList[index].image,
value_description:
dataList[index].description,
value_title: dataList[index].title,
value_datalist: dataList,
newsId: newsIDs[index],
value_index: index,
);
}));
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // add this
children: <Widget>[
ListTile(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
dataList[index].title,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.justify,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
Text(
dataList[index].description.replaceAll('‘', '').replaceAll('&rsquo', ''),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.justify,
maxLines: 4,
style: TextStyle(fontStyle: FontStyle.italic, fontSize: 16),
),
//MyButton(),
]
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
MyButton(title: dataList[index].title,newsId: newsIDs[index],),
],
),
//MyButton(),
),
],
),
),
],
),
),
);
}
else{
if (index != 0 && index % 5 == 0) {
return Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 20.0),
child:
AdmobBanner(
adUnitId: getBannerAdUnitId(),
adSize: bannerSize,
),
),
],
);
}
return SizedBox(
height: 290,
width: MediaQuery.of(context).size.width,
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
InkWell(
onTap: () {
// dataList;
Navigator.push(context,
MaterialPageRoute(builder: (context) {
print(index);
return Newsdetail(
value_image: dataList[index].image,
value_description:
dataList[index].description,
value_title: dataList[index].title,
value_datalist: dataList,
newsId: newsIDs[index],
value_index: index,
);
}));
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // add this
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
child: Image.network(
dataList[index].image,
// width: 300,
height: 150,
fit:BoxFit.fill
),
),
Padding(
padding: const EdgeInsets.all(5.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
dataList[index].title,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.justify,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
Text(
dataList[index].description.replaceAll('‘', '').replaceAll('&rsquo', ''),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.justify,
maxLines: 2,
style: TextStyle(fontStyle: FontStyle.italic, fontSize: 16),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
//crossAxisAlignment: CrossAxisAlignment.end,
children: [
MyButton(title: dataList[index].title,newsId: newsIDs[index],),
],
),
]
),
),
],
),
// Container(
// child: Row(
// children: <Widget>[
// Container(
// height: 80,
// width: 150,
// child: Image.network(
// dataList[index].image,)
// ),
// Expanded(
// child: Padding(
// padding: EdgeInsets.all(8),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// Text(
// dataList[index].title,
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// maxLines: 2,
// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
// ),
// Text(
// dataList[index].description,
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// maxLines: 2,
// style: TextStyle(fontStyle: FontStyle.italic, fontSize: 16),
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children: <Widget>[
// IconButton(
// icon: Image.asset('images/facebook.png',width: 30,height: 30,),
// padding: EdgeInsets.all(0.0),
// onPressed: () {
// //_openFacebook();
// }),
// IconButton(
// icon: Image.asset('images/twitter.png',width: 30,height: 30,),
// padding: EdgeInsets.all(0.0),
// onPressed: () {
// //_openTwitter();
// },
// ),
// IconButton(
// icon: Image.asset(
// 'images/whatsapp.png',width: 25,height: 25,),
// padding: EdgeInsets.all(0.0),
// onPressed: () {
// //_openWhatsapp();
// },
// ),
// ],
// ),
// ]
// ),
// ),
// ),
// MyButton(),
// ],
// )
// ),
),
],
),
),
);
}
},
),
));
}
String getBannerAdUnitId() {
if (Platform.isIOS) {
return 'ca-app-pub-1286371057513373/8623807971';
} else if (Platform.isAndroid) {
return 'ca-app-pub-1286371057513373/8623807971';
}
return null;
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
class MyButton extends StatelessWidget {
String title,newsId;
MyButton({
this.title,
this.newsId,
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return IconButton(
alignment: Alignment.bottomRight,
icon: Icon(Icons.share,color: Colors.black,),
onPressed: ()
{
final RenderBox box = context.findRenderObject();
Share.share('$title\n\n https://www.phulchhab.com/news/$newsId \n via Phulchhab App (Download Now):\n https://play.google.com/store/apps/details?id=com.webpioneer.phulchhab',
//subject: subject,
sharePositionOrigin:
box.localToGlobal(Offset.zero) &
box.size);
},
);
}
}
这可能是问题String newStr = jsonString.substring(1, jsonString.length - 1);
.
你为什么要从响应中去掉花括号? 当您调用jsonDecode
时,它需要一个 json object,但您去掉了{}
。
而且您不能以密钥开头的 json object 。
如果您尝试在不剥去花括号的情况下对其进行解码,它应该可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.