使用API​​中的Json数据制作下拉菜单列表

时间:2019-12-12 07:40:48

标签: json flutter

我是扑扑的新手,在这个项目中,我试图使用“ 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):

1 个答案:

答案 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,
            ),
          ));
      });

根据您的需要自定义构建器,我只使用了文本小部件来检查数据是否正确接收