使用API​​中的Json数据创建下拉菜单列表 [英] making a dropdown menu list using Json data from API

查看:66
本文介绍了使用API​​中的Json数据创建下拉菜单列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是扑朔迷离的新手,在这个项目中,我试图使用"get"方法将来自API的json数据放到我的下拉菜单列表中. 是的,我在另一篇帖子中找到了一个已解决的问题,但解决方案是在与我使用的方法完全不同的方法.我仍要发布此代码的原因是我想了解这是我在此代码上的错误.

i'm new on flutter, in this project i'm trying to put json data from API on my dropdownmenu list using 'get' method. while yes, i found a solved question in another post, but the solution was in a quite different approach than what i was using. the reason why i'm still posting this was i want to understand which was my mistake on this code.

这是我的main.dart代码:

this is my main.dart code:

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文件:

this is my Json file:

[
{
"SSID": "BRT Keren",
"RSSI": "84"
},
{
"SSID": "iPhone",
"RSSI": "27"
},
{
"SSID": "HP-Print-40-LaserJet M12",
"RSSI": "90"
}
]

(部分)调试控制台说:

the (part of) debug console says this:

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. SSID.fetchAPI();返回将来,因此它将异步工作,并且小部件将在获取数据之前构建. 2. SSID.fetchAPI();尚未分配给任何变量 3. _ssids= List<SSID>();从未设置接收到的数据

Few issues visible are 1. SSID.fetchAPI(); returns future so it will work asynchronous and widget will build before getting data. 2. SSID.fetchAPI(); has not been assigned to any variable 3._ssids= List<SSID>(); has never been set with recieved data

因此将Future小部件与future : SSID.fetchAPI()

So use Future widget with 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{

在这种情况下,构建器将为

in that case builder will be

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

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

Customize the builder as per your need i have only used a Text widget to check if data is recieved correctly

这篇关于使用API​​中的Json数据创建下拉菜单列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆