我是扑扑的新手,在这个项目中,我试图使用“ get”方法将来自API的json数据放到我的下拉菜单列表中。 是的,我在another post中找到了一个已解决的问题,但是解决方案与我使用的方法完全不同。我仍要发布此代码的原因是我想了解这是我在此代码上的错误。
这是我的main.dart代码:
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(PrototypeApp());
class PrototypeApp extends StatefulWidget{
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return PrototypeAppState();
}
}
class SSID {
String name;
String percentage;
SSID({this.name, this.percentage});
factory SSID.generateSSID(Map<String,dynamic>object){
return SSID(
name: object['SSID'].toString(),
percentage:object['RSSI'].toString(),
);
}
static Future<SSID> fetchAPI() async{
String url='http://10.0.2.2/data/connection.json';
var apiResult= await http.get(url,headers: {"Accept": "application/json"});
var jsonObject=json.decode(apiResult.body);
return SSID.generateSSID(jsonObject[0]);
}
}
class PrototypeAppState extends State<PrototypeApp> {
bool _obsstate=true;
List<DropdownMenuItem<SSID>>_dropdownMenuItems;
SSID _selectedSSID;
List _ssids;
@override
void initState(){
SSID.fetchAPI();
//isnt this meant that i had fetch Json data with this function, and put them on Class SSID?
_ssids= List<SSID>();
//then i put them to a new List variable on this class
_dropdownMenuItems=buildDropdownMenuItems(_ssids);
//should've been fine to do this isnt it?
super.initState();
}
List<DropdownMenuItem<SSID>>buildDropdownMenuItems(List ssids){
List<DropdownMenuItem<SSID>>items=List();
for (SSID ssid in ssids) {
items.add(
DropdownMenuItem(
value: ssid,
child: Row(
children:[
Text(ssid.name),
SizedBox(width: 20.0,),
Text(ssid.percentage),
Text('%'),
]
)
),
);
}
return items;
}
onChangeDropdownItem(SSID selectedsSSID){
setState((){
_selectedSSID=selectedsSSID;
});
}
@override
Widget build(BuildContext context){
return MaterialApp(
debugShowCheckedModeBanner: false,
home:Scaffold(
appBar: AppBar(
title:Text('WIFI Configuration'),
),
body: Container(
child:Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children:[
Text('pick your Wifi network'),
SizedBox(height: 20.0,),
DropdownButton(
value: _selectedSSID,
items: _dropdownMenuItems,
onChanged: onChangeDropdownItem,
),
SizedBox(height: 10.0,),
Container(
width:300,
child:TextField(
obscureText:_obsstate,
decoration: InputDecoration(
hintText: 'type SSID password',
),
),
),
Text('Selected network:${_selectedSSID.name}'),
RaisedButton(
child: Text('Login'),
onPressed:null
),
],
),
),
),
)
);
}
}
这是我的Json文件:
[
{
"SSID": "BRT Keren",
"RSSI": "84"
},
{
"SSID": "iPhone",
"RSSI": "27"
},
{
"SSID": "HP-Print-40-LaserJet M12",
"RSSI": "90"
}
]
(部分)调试控制台说:
I/flutter ( 9146): The following NoSuchMethodError was thrown building PrototypeApp(dirty, state:
I/flutter ( 9146): PrototypeAppState#b125a):
I/flutter ( 9146): The getter 'name' was called on null.
I/flutter ( 9146): Receiver: null
I/flutter ( 9146): Tried calling: name
I/flutter ( 9146):
I/flutter ( 9146): The following NoSuchMethodError was thrown building PrototypeApp(dirty, state:
I/flutter ( 9146): PrototypeAppState#b125a):
I/flutter ( 9146): The getter 'name' was called on null.
I/flutter ( 9146): Receiver: null
I/flutter ( 9146): Tried calling: name
I/flutter ( 9146):
答案 0 :(得分:0)
可见的问题很少
1. SSID.fetchAPI();
返回将来,因此它将异步工作,并且小部件将在获取数据之前构建。
2. SSID.fetchAPI();
尚未分配给任何变量
3。_ssids= List<SSID>();
从未设置接收到的数据
因此,将Future窗口小部件与future : SSID.fetchAPI()
FutureBuilder(
future: SSID.fetchAPI(),
initialData: "Loading text..",
builder: (BuildContext context, AsyncSnapshot<SSID> ssid) {
return new SingleChildScrollView(
padding: new EdgeInsets.all(8.0),
child: new Text(
ssid.name,
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 19.0,
),
));
});
我也认为
static Future<SSID> fetchAPI() async{
应该是
static Future<List<SSID>> fetchAPI() async{
在这种情况下,构建器将为
FutureBuilder(
future: SSID.fetchAPI(),
initialData: "Loading text..",
builder: (BuildContext context, AsyncSnapshot<List<SSID>> ssids) {
return new SingleChildScrollView(
padding: new EdgeInsets.all(8.0),
child: new Text(
ssids.length.toString(),
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 19.0,
),
));
});
根据您的需要自定义构建器,我只使用了文本小部件来检查数据是否正确接收