繁体   English   中英

Flutter 显示服务器数据/来自 json 的响应

[英]Flutter display server data / response from json

我已经构建了一个从recipeURL读取 json 的页面,我希望它在 json 文件中显示product_name值。 但是由于某种原因,我future fetchData () class 没有被读取,因为我的 if else 语句中没有显示任何文本。 我在这里错过了一个简单的疏忽吗?

编辑:主 dart 文件是我的主屏幕。 这是创建我的导航栏的地方。 当用户点击相应的图标时,他们将被重定向到其他页面。 我在传递BarcodePage(title:title); 作为我主文件中的参数,第 26 行,可以在 Class 下Class MyAppState extends State<MyApp> {

我的主要 dart 文件:

import 'package:flutter/material.dart';

import 'pages/BarcodePage.dart';
import 'pages/FoodPage.dart';
import 'pages/RecipePage.dart';
import 'pages/ShoppingPage.dart';


void main() {
  runApp(MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()),);
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState(){
    return MyAppState();
  }
}


class MyAppState extends State<MyApp> {
 int _selectedPage =0;
 final _pageOptions= [
    FoodPage(),
    RecipePage(),
    BarcodePage(title: ,),
    ShoppingPage(),
  ];

  

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //title: 'Best B4',
        theme: ThemeData(
         primarySwatch: Colors.teal,),
         debugShowCheckedModeBanner: false,
         home: Scaffold (
           appBar: AppBar(
            title:Text(
              'BestB4',
              style: TextStyle(
                  fontFamily: 'PacificoRegular',
                  fontSize: 30,
              ),
            ),
            backgroundColor: Colors.teal,
            elevation: 20,
            actions: [
              IconButton(
                icon: Icon(Icons.qr_code_2_rounded),
                tooltip: 'Add item',
                onPressed:(){
                   Navigator.push(
                     context, 
                     MaterialPageRoute(builder: (context) => BarcodePage()));
                },
              )
              ],
              //ONPRESSED MENU OPEN
           ),
            body:_pageOptions[_selectedPage],
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              backgroundColor: Colors.teal,
              selectedItemColor: Colors.white,
              unselectedItemColor: Colors.white70,
              iconSize: 40,
              selectedFontSize: 15,
              unselectedFontSize: 15,
              currentIndex:_selectedPage,
              onTap: (int index) {
                setState(() {
                  _selectedPage  = index;
                });
              },
              items: [
                BottomNavigationBarItem(
                  icon:Icon(Icons.restaurant_rounded),
                  label: 'Food',
                  ), //, title:Text('Food')
                BottomNavigationBarItem(
                  icon:Icon(Icons.menu_book_rounded),
                  label:'Recipes',
                  ),//, title:Text('Recipes')
                BottomNavigationBarItem(
                  icon:Icon(Icons.add_outlined),
                  label:'Add',
                  ),//, title:Text('Add')
                 BottomNavigationBarItem(
                  icon:Icon(Icons.shopping_cart_rounded),
                  label:'Shopping',
                  ),//,title:Text('Shopping')
              ],
          ),
      ),
      ); 
  }
}

我的 BarcodePage dart 文件:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as p;
import 'package:flutter/services.dart';
import 'package:barcode_scan2/barcode_scan2.dart';
import 'package:http/http.dart';



class BarcodePage extends StatefulWidget{
  const BarcodePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _BarcodePageState createState() => _BarcodePageState();
}

var futuredata = {};

class _BarcodePageState extends State<BarcodePage> {
  int counter=0;
  String result= "";

  Future _scanBarcode() async{
    try{
      ScanResult scanResult = await BarcodeScanner.scan();
      String barcodeResult = scanResult.rawContent;
      setState(() {
        result = barcodeResult;
      });

    } on PlatformException catch (ex) {
      if (ex.code == BarcodeScanner.cameraAccessDenied) {
        setState((){
        result = "CAMERA PERMISSION WAS DENIED. \n EDIT THIS IN YOUR SETTINGS";
      });
    }else {
      setState(() {
        result = "404 ERROR UNKNOWN $ex";
      });
    }
  } on FormatException {
    setState(() {
      result = "SCAN AN ITEM";
    });
  } catch (ex){
    setState(() {
        result = "404 ERROR UNKNOWN $ex";
      });
    }
  }
  @override
  void initState() {}

  fetchmydata() async {
    var request = p.Request(
        'GET',
        Uri.parse(
            'https://world.openfoodfacts.org/api/v0/product/5060391623139.json'));

    StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      // print(await response.stream.bytesToString());
      var data = await response.stream.bytesToString();
      futuredata = json.decode(data);
    } else {
      print(response.reasonPhrase);
    }
  }

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.teal,
        title:Text('Add an item',
        style: TextStyle(
        fontFamily: 'Fredoka',
        fontSize: 25,
        ),
        ),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          FutureBuilder(
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting)
                return Center(
                  child: Container(
                    child: CircularProgressIndicator(),
                    height: 50,
                    width: 50,
                  ),
                );
              else if (snapshot.connectionState == ConnectionState.done)
                return ListTile(
                  title: Text(futuredata["product"]["product_name"].toString()),
                  subtitle: Text("France:" +
                      futuredata["product"]["product_name_en"].toString()),
                );
              else {
                return Container(
                  child: CircularProgressIndicator(),
                  height: 50,
                  width: 50,
                );
              }
            },
            future: fetchmydata(),
          )
        ],
      ),
      floatingActionButton: FloatingActionButton.extended(
        backgroundColor: Color.fromRGBO(51, 171, 160, 100),
        icon: Icon(Icons.camera_alt),
        label: Text("Scan"),
        onPressed: _scanBarcode,
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

Json 文件如下所示:

JSON 链接: https://world.openfoodfacts.org/api/v0/product/5060391623139.json

在此处输入图像描述

在此处输入图像描述

你可以这样读你的json

var futuredata = {};
var productname=    futuredata["product"]["product_name"]

你的获取方法是这样的

 fetchmydata() async {
    var request = p.Request(
        'GET',
        Uri.parse(
            'https://world.openfoodfacts.org/api/v0/product/5060391623139.json'));

    StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      // print(await response.stream.bytesToString());
      var data = await response.stream.bytesToString();
      futuredata = json.decode(data);
    } else {
      print(response.reasonPhrase);
    }
  }

使用 model Class SampleModel? 我的模型 = null; fetchmydata() async { var request = p.Request( 'GET', Uri.parse( 'https://world.openfoodfacts.org/api/v0/product/5060391623139.json'));

    StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      // print(await response.stream.bytesToString());
      var data = await response.stream.bytesToString();
      futuredata = json.decode(data);
      Mymodel = SampleModel.fromJson(futuredata);
    } else {
      print(response.reasonPhrase);
    }
  }
  1. 在方法中,我们首先从 json 读取数据作为字符串或文本
  2. 然后我们将来自服务器的字符串类型或文本解码为 map 类型

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

SampleCode Dartpad 实时代码检查

import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:http/http.dart' as p;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

var futuredata = {};

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  void initState() {}

  fetchmydata() async {
    var request = p.Request(
        'GET',
        Uri.parse(
            'https://world.openfoodfacts.org/api/v0/product/5060391623139.json'));

    StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      // print(await response.stream.bytesToString());
      var data = await response.stream.bytesToString();
      futuredata = json.decode(data);
    } else {
      print(response.reasonPhrase);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          FutureBuilder(
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting)
                return Center(
                  child: Container(
                    child: CircularProgressIndicator(),
                    height: 50,
                    width: 50,
                  ),
                );
              else if (snapshot.connectionState == ConnectionState.done)
                return ListTile(
                  title: Text(futuredata["product"]["product_name"].toString()),
                  subtitle: Text("France:" +
                      futuredata["product"]["product_name_en"].toString()),
                );
              else {
                return Container(
                  child: CircularProgressIndicator(),
                  height: 50,
                  width: 50,
                );
              }
            },
            future: fetchmydata(),
          )
        ],
      ),
    );
  }
}

样本模型类

///
/// Code generated by jsonToDartModel https://ashamp.github.io/jsonToDartModel/
///
class SampleModelProduct {
/*
{
  "_id": "5060391623139",
  "_keywords": [
    "peanut"
  ],
  "product_name": "Peanut butter",
  "product_name_en": "Peanut butter",
  "product_name_fr": "Peanut butter"
}
*/

  String? Id;
  List<String?>? Keywords;
  String? productName;
  String? productNameEn;
  String? productNameFr;

  SampleModelProduct({
    this.Id,
    this.Keywords,
    this.productName,
    this.productNameEn,
    this.productNameFr,
  });

  SampleModelProduct.fromJson(Map<String, dynamic> json) {
    Id = json['_id']?.toString();
    if (json['_keywords'] != null) {
      final v = json['_keywords'];
      final arr0 = <String>[];
      v.forEach((v) {
        arr0.add(v.toString());
      });
      Keywords = arr0;
    }
    productName = json['product_name']?.toString();
    productNameEn = json['product_name_en']?.toString();
    productNameFr = json['product_name_fr']?.toString();
  }

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    data['_id'] = Id;
    if (Keywords != null) {
      final v = Keywords;
      final arr0 = [];
      v!.forEach((v) {
        arr0.add(v);
      });
      data['_keywords'] = arr0;
    }
    data['product_name'] = productName;
    data['product_name_en'] = productNameEn;
    data['product_name_fr'] = productNameFr;
    return data;
  }
}

class SampleModel {
/*
{
  "code": "5060391623139",
  "product": {
    "_id": "5060391623139",
    "_keywords": [
      "peanut"
    ],
    "product_name": "Peanut butter",
    "product_name_en": "Peanut butter",
    "product_name_fr": "Peanut butter"
  },
  "status": 1,
  "status_verbose": "product found"
}
*/

  String? code;
  SampleModelProduct? product;
  int? status;
  String? statusVerbose;

  SampleModel({
    this.code,
    this.product,
    this.status,
    this.statusVerbose,
  });

  SampleModel.fromJson(Map<String, dynamic> json) {
    code = json['code']?.toString();
    product = (json['product'] != null)
        ? SampleModelProduct.fromJson(json['product'])
        : null;
    status = json['status']?.toInt();
    statusVerbose = json['status_verbose']?.toString();
  }

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    data['code'] = code;
    if (product != null) {
      data['product'] = product!.toJson();
    }
    data['status'] = status;
    data['status_verbose'] = statusVerbose;
    return data;
  }
}

尝试使用 flutter 包 pub run build_runner build 创建 agdart 文件。 flutter 将自动创建您的绑定 class 工厂。 一旦你创建了绑定类 flutter 将自动编码你的绑定 class,包括嵌套类。 我个人认为自动化是处理服务器与 json 的所有交互的方式。 您要使用 future.g.dart 代码生成器的原因是为了减少错误和不正确类型转换的可能性。

file.dart
factory ProductView.fromJson(Map<String, dynamic> json) =>
      _$ProductFromJson(json);
Map<String, dynamic> toJson() => _$ProductViewToJson(this);

file.g.dart


ProductView _$ProductViewFromJson(Map<String, dynamic> json) {
  return
ProductView(
    json['field1'] as int,
    json['field2'] as String,
    json['field3'] == null
        ? null
        : DateTime.parse(json['field3'] as String),
  );
}

Map<String, dynamic> _$ProjectViewToJson(ProductView instance) =>
    <String, dynamic>{
      'field1': instance.field1,
      'field2': instance.field2,
      'field3': instance.field3?.toIso8601String(),
    };

解码 json

 var client = http.Client();
      Map<String, String> headers = new HashMap();
      headers['Accept'] = 'application/json';
      headers['Content-Type'] = 'application/json';
      headers['Authorization'] = 'Bearer $token';
var response = await client.get(url, headers: headers).timeout(_TIMEOUT);
    var parsed = json.decode(response.body);
    var view = ProductView.fromJson(parsed);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM