HTTP POST リクエストの結果からリストビュー ビルダーにデータを表示しようとしましたが、Flutter で結果が表示されましたが、次のエラーが発生しました。
現在、在庫がありませんので、大変助かっております。助けてくれてありがとう。
import 'dart:convert';
import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:sunutontine/models/tontine.dart';
import 'package:sunutontine/models/post_result.dart';
import 'package:http/http.dart' as http;
import 'package:sunutontine/utils/constants.dart';
import 'package:sunutontine/pages/cotisation_page.dart';
import 'package:device_info/device_info.dart';
class TontineLanceeListeState extends State<TontineLanceeListe> {
final globalKey = new GlobalKey<ScaffoldState>();
List<PostResult> postResult = List();
PostResult resultFromJson(String str) =>
PostResult.fromJson(json.decode(str));
String resultToJson(PostResult data) => json.encode(data.toJson());
bool _isLoading = false;
BuildContext context1;
ListTile _buildItemsForListView(BuildContext context, int index) {
return ListTile(
title: Container(
child: Stack(
children: <Widget>[
_semiCircleContainer(),
_semiCircleContainer(),
Container(
padding: EdgeInsets.only(top: 45),
child: Card(
elevation: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 15)),
Row(children: <Widget>[Padding(padding: EdgeInsets.only(left: 10)),Text(Texts.CAGNOTTE, style: TextStyle(fontSize: 18.0)), Text(postResult[index].mestontines[index].mtverser, style: TextStyle(color: Colors.orange[900], fontSize: 18.0, fontWeight: FontWeight.bold),)]),
Padding(padding: EdgeInsets.all(3)),
Divider(),
Padding(padding: EdgeInsets.all(3)),
Row(children: <Widget>[Padding(padding: EdgeInsets.only(left: 10)), Text(Texts.TONTINE, style: TextStyle(fontSize: 16.0)), Text(postResult[index].mestontines[index].nom, style: TextStyle(color: Colors.grey[900], fontSize: 16.0, fontWeight: FontWeight.bold))]),
Padding(padding: EdgeInsets.all(3)),
Row(children: <Widget>[Padding(padding: EdgeInsets.only(left: 10)), Text(Texts.MONTANT, style: TextStyle(fontSize: 16.0)), Text(postResult[index].mestontines[index].mtacotiser, style: TextStyle(color: Colors.grey[900], fontSize: 16.0, fontWeight: FontWeight.bold))]),
Padding(padding: EdgeInsets.all(3)),
Row(children: <Widget>[Padding(padding: EdgeInsets.only(left: 10)), Text(Texts.PERIOD, style: TextStyle(fontSize: 16.0)), Text(postResult[index].mestontines[index].periode, style: TextStyle(color: Colors.grey[900], fontSize: 16.0, fontWeight: FontWeight.bold))]),
Padding(padding: EdgeInsets.all(3)),
Row(children: <Widget>[Padding(padding: EdgeInsets.only(left: 10)), Text(Texts.DURATION, style: TextStyle(fontSize: 16.0)), Text(postResult[index].mestontines[index].duree, style: TextStyle(color: Colors.grey[900], fontSize: 16.0, fontWeight: FontWeight.bold))]),
Padding(padding: EdgeInsets.all(3)),
Row(children: <Widget>[Padding(padding: EdgeInsets.only(left: 10)), Text(Texts.START_DATE, style: TextStyle(fontSize: 16.0)), Text(postResult[index].mestontines[index].datedebut, style: TextStyle(color: Colors.grey[900], fontSize: 16.0, fontWeight: FontWeight.bold))]),
Padding(padding: EdgeInsets.all(3)),
Row(children: <Widget>[Padding(padding: EdgeInsets.only(left: 10)), Text(Texts.END_DATE, style: TextStyle(fontSize: 16.0)), Text(postResult[index].mestontines[index].datefin, style: TextStyle(color: Colors.grey[900], fontSize: 16.0, fontWeight: FontWeight.bold))]),
Padding(padding: EdgeInsets.all(3)),
Row(
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 10)),
Text(Texts.STATE, style: TextStyle(fontSize: 16.0)),
Text(postResult[index].mestontines[index].etat, style: TextStyle(color: Colors.grey[900], fontSize: 16.0, fontWeight: FontWeight.bold)),
Padding(padding: EdgeInsets.only(left: 60)),
Text(Texts.HAND_NUMBER, style: TextStyle(fontSize: 16.0)), Text(postResult[index].mestontines[index].nb, style: TextStyle(color: Colors.grey[900], fontSize: 16.0, fontWeight: FontWeight.bold))]),
Padding(padding: EdgeInsets.only(bottom: 10)),
]
),
),
),
Container(
padding: EdgeInsets.only(top: 310),
child: Card(
elevation: 5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 15)),
Row(
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 12)),
Text(Texts.NEXT_CASH, style: TextStyle(fontSize: 18.0, color: Colors.orange[900])),
MaterialButton(
onPressed: null,
child: Text(Texts.SEE_ALL, style: TextStyle(color: Colors.orange[900], fontSize: 18)),
)
]
),
Padding(padding: EdgeInsets.all(3)),
Divider(),
Padding(padding: EdgeInsets.all(3)),
Row(
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 10)),
Icon(Icons.calendar_today, color: Colors.orange[900],),
Padding(padding: EdgeInsets.only(left: 3)),
Text('12 Avril 2020', style: TextStyle(color: Colors.grey, fontSize: 13),) ,
Padding(padding: EdgeInsets.only(left: 8)),
Container(
decoration: BoxDecoration(border: Border.all(color: Colors.red)),
child: IconButton(icon: Icon(Icons.search, color: Colors.red,), onPressed: null),
),
//Padding(padding: EdgeInsets.only(left: 5)),
MaterialButton(
onPressed: _goToCotisationScreen,
child: Container(
decoration: BoxDecoration(border: Border.all(color: Colors.green)),
child: Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.file_download, color: Colors.green,),
onPressed: null
),
Text("COTISER", style: TextStyle(color: Colors.green),),
Padding(padding: EdgeInsets.only(right: 3)),
],
)
),
),
Padding(padding: EdgeInsets.only(bottom: 5)),
]
),
Divider(),
Row(
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 10)),
Icon(Icons.calendar_today, color: Colors.orange[900],),
Padding(padding: EdgeInsets.only(left: 3)),
Text('12 Mai 2020', style: TextStyle(color: Colors.grey, fontSize: 13),) ,
Padding(padding: EdgeInsets.only(left: 8)),
Container(
decoration: BoxDecoration(border: Border.all(color: Colors.red)),
child: IconButton(icon: Icon(Icons.search, color: Colors.red,), onPressed: null),
),
//Padding(padding: EdgeInsets.only(left: 5)),
MaterialButton(
onPressed: _goToCotisationScreen,
child: Container(
decoration: BoxDecoration(border: Border.all(color: Colors.green)),
child: Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.file_download, color: Colors.green,),
onPressed: null
),
Text("COTISER", style: TextStyle(color: Colors.green),),
Padding(padding: EdgeInsets.only(right: 3)),
],
)
),
),
Padding(padding: EdgeInsets.only(bottom: 5)),
]
),
Padding(padding: EdgeInsets.only(top: 15)),
Divider(),
Row(
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 12)),
Text(Texts.TEGGI, style: TextStyle(fontSize: 18.0, color: Colors.green)),
Padding(padding: EdgeInsets.only(left: 80)),
MaterialButton(
onPressed: null,
child: Text(Texts.SEE_ALL, style: TextStyle(color: Colors.green, fontSize: 18)),
)
]
),
Divider(),
Row(
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 10)),
Icon(Icons.calendar_today, color: Colors.green,),
Padding(padding: EdgeInsets.only(left: 3)),
Text('12 juin 2020 \nSokhna Khady Ngom', style: TextStyle(color: Colors.grey, fontSize: 18),) ,
//Padding(padding: EdgeInsets.only(left: 5)),
Padding(padding: EdgeInsets.only(bottom: 5)),
]
),
Divider(),
Row(
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 10)),
Icon(Icons.calendar_today, color: Colors.green,),
Padding(padding: EdgeInsets.only(left: 3)),
Text('12 juin 2020 \nSokhna Khady Ngom', style: TextStyle(color: Colors.grey, fontSize: 18),) ,
//Padding(padding: EdgeInsets.only(left: 5)),
Padding(padding: EdgeInsets.only(bottom: 5)),
]
),
],
),
),
)
],
),
),
);
}
Future<bool> _onWillPop() {
return showDialog(
context: context,
builder: (context) => AlertDialog(
elevation: 10,
backgroundColor: Colors.orange[900],
content: Text("Voulez-vous vraiment\n quitter SunuTontine ?", style: TextStyle(color: Colors.white)),
actions: <Widget>[
FlatButton(
shape: Border.all(color: Colors.white),
onPressed: () => Navigator.of(context).pop(false),
child: Text('NON', style: TextStyle(color: Colors.white)),
),
Padding(padding: EdgeInsets.only(left: 60)),
FlatButton(
color: Colors.white,
shape: Border.all(color: Colors.white),
onPressed: () => exit(0),
/*Navigator.of(context).pop(true)*/
child: Text('OUI', style: TextStyle(color: Colors.orange[900])),
),
],
),
) ??
false;
}
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(
key: globalKey,
body: _isLoading ? CircularProgressIndicator() : ListView.builder(
itemCount: postResult == null ? 0 : postResult.length,
itemBuilder: _buildItemsForListView,
)
),
onWillPop: _onWillPop);
}
Future<String> getData() async {
var uuid = await _getId();
var reqestData = {'uuid':uuid, 'idclient': widget.id };
var response = await http.post(
"https://numherit-labs.com/sunutontine/ScriptMobileEtontine/tontineslancees.php",
body: reqestData,
);
var message = jsonDecode(response.body);
if(response.statusCode == 200 && message['statut'] == 'OK'){
print(message);
return message;
}
else{
return message;
}
}
Future loadData() async {
// var uuid = await _getId();
print(widget.id);
setState(() {
_isLoading = true;
});
String jsonString = await getData();
final result = resultFromJson(jsonString);
postResult.add(result);
setState(() {
_isLoading = false;
});
}
@override
void initState() {
super.initState();
loadData();
}
Future<String> _getId() async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (Theme.of(context).platform == TargetPlatform.iOS) {
return iosDeviceInfo.identifierForVendor; // unique ID on iOS
} else {
AndroidDeviceInfo androidDeviceInfo = await deviceInfo.androidInfo;
return androidDeviceInfo.androidId; // unique ID on Android
}
}
///////////////////////////////////////////////////////////////////////
Widget _semiCircleContainer() {
return new Container(
width: 100.0,
height: 100.0,
margin: EdgeInsets.only(left: 110.0, top: 30.0),
decoration: mySemiCircleDecoration(),
);
}
BoxDecoration mySemiCircleDecoration() {
return BoxDecoration(
borderRadius: BorderRadius.circular(300.0),
//shape: BoxShape.circle,
color: Colors.white,
);
}
void _goToCotisationScreen(){
Navigator.pushReplacement(
context,
new MaterialPageRoute(builder: (context) => CotisationPage()),
);
}
}
class TontineLanceeListe extends StatefulWidget {
TontineLanceeListe({Key key, this.id}) : super(key: key);
int id;
@override
createState() => TontineLanceeListeState();
}
ここに私のモデルがあります:
tontines.dart
class Tontine {
String id;
String nom;
String code;
String nbmax;
String nbmin;
String nb;
String periode;
String mtacotiser;
String tontinier;
String duree;
String dateprevue;
String datedebut;
String postecash;
String etat;
String etattirage;
String mtverser;
DateTime datecreation;
String usercreation;
String datemodif;
String usermodif;
String modetirage;
String description;
String datecotise;
String datefin;
Tontine(
{this.id,
this.nom,
this.code,
this.nbmax,
this.nbmin,
this.nb,
this.periode,
this.mtacotiser,
this.tontinier,
this.duree,
this.dateprevue,
this.datedebut,
this.postecash,
this.etat,
this.etattirage,
this.mtverser,
this.datecreation,
this.usercreation,
this.datemodif,
this.usermodif,
this.modetirage,
this.description,
this.datecotise,
this.datefin});
factory Tontine.fromJson(Map<String, dynamic> json) {
return Tontine(
id : json['id'],
nom : json['nom'],
code : json['code'],
nbmax : json['nbmax'],
nbmin : json['nbmin'],
nb : json['nb'],
periode : json['periode'],
mtacotiser : json['mtacotiser'],
tontinier : json['tontinier'],
duree : json['duree'],
dateprevue : json['dateprevue'],
datedebut : json['datedebut'],
postecash : json['postecash'],
etat : json['etat'],
etattirage : json['etattirage'],
mtverser : json['mtverser'],
datecreation : json['datecreation'],
usercreation : json['usercreation'],
datemodif : json['datemodif'],
usermodif : json['usermodif'],
modetirage : json['modetirage'],
description : json['description'],
datecotise : json['datecotise'],
datefin : json['datefin']
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['nom'] = this.nom;
data['code'] = this.code;
data['nbmax'] = this.nbmax;
data['nbmin'] = this.nbmin;
data['nb'] = this.nb;
data['periode'] = this.periode;
data['mtacotiser'] = this.mtacotiser;
data['tontinier'] = this.tontinier;
data['duree'] = this.duree;
data['dateprevue'] = this.dateprevue;
data['datedebut'] = this.datedebut;
data['postecash'] = this.postecash;
data['etat'] = this.etat;
data['etattirage'] = this.etattirage;
data['mtverser'] = this.mtverser;
data['datecreation'] = this.datecreation;
data['usercreation'] = this.usercreation;
data['datemodif'] = this.datemodif;
data['usermodif'] = this.usermodif;
data['modetirage'] = this.modetirage;
data['description'] = this.description;
data['datecotise'] = this.datecotise;
data['datefin'] = this.datefin;
return data;
}
}
post_result.dart
import 'tontine.dart';
class PostResult {
String statut;
int errorCode;
String errorMessage;
List<Tontine> mestontines;
PostResult({
this.statut,
this.errorCode,
this.errorMessage,
this.mestontines,
});
factory PostResult.fromJson(Map<String, dynamic> json) => PostResult(
statut: json["responseCode"],
errorCode: json["errorCode"],
errorMessage: json["errorMessage"],
mestontines: List<Tontine>.from(
json["mestontines"].map((x) => Tontine.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"responseCode": statut,
"errorCode": errorCode,
"errorMessage": errorMessage,
"mestontines": List<dynamic>.from(mestontines.map((x) => x.toJson())),
};
}
そして、私の投稿リクエストは次のようなものを返します:
{
"statut":"OK",
"errorCode":0,
"errorMessage":"",
"mestontines":[
{
"id":"1",
"nom":"test tontine",
"code":"TNE-5994945946",
"nbmax":"3",
"nb":"2",
"nbmin":null,
"periode":"30",
"mtacotiser":"10000",
"tontinier":"1439",
"duree":"3",
"dateprevue":"2020-01-10",
"datedebut":"2017-11-21",
"postecash":"00221775373761",
"etat":"1",
"etattirage":"0",
"mtverser":"0",
"modetirage":"1",
"description":"",
"datecotise":"20",
"periodicite":"Mensuelle",
"libmodetirage":"Al\u00e9atoire",
"enattente":1,
"idperiodicite":"4"
}
]
}