本文介绍了Flutter:RangeError(索引):无效值:有效值范围为空:-1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个这样的JSON文件:


json1(


我认为在 Build 类中可能有问题:

 ════ widget由小部件库捕获的异常═════════════════════════════════════════ ══════════════
在构建Builder(dirty)时引发了以下RangeError:
RangeError(索引):无效值:有效值范围为空:-1

相关的引起错误的小部件是:
Builder file:/// D:/Flutter/Test/load_data/lib/json2_page3.dart:80:17
发生异常时被扔了,这是sta ck:
#0列表。[](dart:core-patch / growable_array.dart:177:60)
#1 _ShowContinentState.build。<匿名闭包> (包:load_data / json2_page3.dart:83:38)
#2 Builder.build(包:flutter / src / widgets / basic.dart:7183:48)
#3 StatelessElement.build(包:flutter / src / widgets / framework.dart:4644:28)
#4 ComponentElement.performRebuild(package:flutter / src / widgets / framework.dart:4570:15)

请帮助我,这是主文件

  import'包装:Flutter / material.dart'; 
import‘package:load_data / model / json2_model.dart’;
import‘package:load_data / service / json1_service.dart’;
import‘package:load_data / service / json2_service.dart’;
import‘model / json1_model.dart’;

类Json2Page3扩展了StatefulWidget {
@override
_Json2Page3State createState()=> _Json2Page3State();
}

class _Json2Page3State扩展了State< Json2Page3> {
List< Json2> json2 = [];
List< String> _continent = [];
@override
void initState(){
super.initState();
setState((){
Json2Services.getData()。then((data){
setState((){
json2 = data;
_continent = json2。 map< String>((x)=> x.json2Continent).toSet()。toList();
});
});
});
}

@override
小部件构建(BuildContext上下文){
return DefaultTabController(
长度:_continent.length,
子代:脚手架(
appBar:AppBar(
标题:Text('Page 2'),
底部:TabBar(tabs:_continent.map((String name)=> Tab(text:name) ).toList()),
),
正文:TabBarView(
子级:_continent.map((String name){
return ShowContinent(
json2:List< ; Json2> .from(json2).. retainWhere((e)=> e.json2Continent == name),
);
})。toList()),
)) ;
}
}

类ShowContinent扩展了StatefulWidget {
final List< Json2> json2;
ShowContinent({this.json2});
@override
_ShowContinentState createState()=> _ShowContinentState(json2);
}

类_ShowContinentState扩展了State< ShowContinent> {
final List< Json2> json2;
List< Json1> json1 = [];

_ShowContinentState(this.json2);

@override
void initState(){
super.initState();
Json1Services.getData()。then((data){
setState((){
json1 = data;
});
});
}

@override
小部件build(BuildContext context){
return Column(
children:[
for(Json2 j2 in json2 )
Row(
mainAxisAlignment:MainAxisAlignment.spaceAround,
子级:[
Text(j2.json2Country.toUpperCase()),
for(int i = 0;我< j2.json2Language.length; i ++)
Builder(
builder:(_){
int index = json1.indexWhere((e)=> e.json1Language == j2 .json2Language [i]);
返回Row(
个孩子:[
Image.network(json1 [index] .json1Icon),
Text(json1 [index] .json1Code) ,
],
),
},

],
),
],
);
}
}



解决方案

您可以在

下面复制粘贴运行完整代码,可以使用 addPostFrameCallback bool isLoading 以检查加载状态

isLoading == true 时,返回 CircularProgressIndicator()

代码段

  bool isLoading = true; 

@override
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
Json1Services.getData()。then((data){
setState((){
json1 = data;
isLoading = false;
});
});
});
}

@override
小部件构建(BuildContext上下文){
return isLoading
吗?中心(孩子:CircularProgressIndicator())
:列(

工作演示



完整代码

  import 'package:flutter / material.dart'; 

import'dart:convert';

List< Json2> json2FromJson(String str)=>
List< ; Json2> .from(json.decode(str).map((x)=> Json2.fromJson(x))));

字符串json2ToJson(List< Json2> data)=>
json.encode(List< dynamic> .from(data.map((x)=> x.toJson()))));

List< Json1> json1FromJson(String str )=>
List< Json1> .from(json.decode(str).map((x)=> Json1.fromJson(x))));

字符串json1ToJson( List< Json1>数据)=>
json.encode(List< dynamic> .from(data.map((x)=> x.toJson()))));

类Json1 {
J son1({
this.json1Language,
this.json1Icon,
this.json1Code,
});

字符串json1语言;
字符串json1Icon;
字符串json1Code;

factory Json1.fromJson(Map< String,dynamic> json)=> Json1(
json1Language:json [ json1Language],
json1Icon:json [ json1Icon],
json1Code:json [ json1Code],
);

Map< String,dynamic> toJson()=> {
json1Language:json1Language,
json1Icon:json1Icon,
json1Code:json1Code,
};
}

class Json2 {
Json2({
this.json2Country,
this.json2Continent,
this.json2Language,
});

字符串json2Country;
字符串json2Continent;
List< String> json2Language;

factory Json2.fromJson(Map< String,dynamic> json)=> Json2(
json2Country:json [ json2Country],
json2Continent:json [ json2Continent],
json2Language:List< String> .from(json( json2Language] .map((x)=> x)),
);

Map< String,dynamic> toJson()=> {
json2Country:json2Country,
json2Continent:json2Continent,
json2Language:List< dynamic> .from(json2Language.map((x)=> x )),
};
}

类Json2Services {
static Future< List< List< Json2>> getData()async {
等待Future.delayed(Duration(seconds:5),(){});

字符串jsonString ='''
[
{
json2Country: Canada,
json2Continent: North美式,
json2Language:[
法语,
英语
]
},
{
json2Country:墨西哥,
json2Continent:北美,
; json2Language:[
Spanish,
English
]
},
{
json2Country:英国,
json2Continent:欧洲,
; json2Language:[
English;
]
},
{
json2Country:法国,
json2Continent:欧洲,
json2Language:[
French
]
},
{
json2Country:西班牙,
json2Continent:欧洲,
json2Language:[
Spanish
]
}
]
’’’;

return Future.value(json2FromJson(jsonString));
}
}

类Json1Services {
static Future< List< List< Json1> getData()async {
等待Future.delayed(Duration(seconds:5),(){});
字符串jsonString ='''
[
{
json1Language: English,
json1Icon: https:// www .countryflags.io / gb / flat / 64.png,
json1Code: en
},
{
json1Language:法语,
json1Icon: https://www.countryflags.io/fr/flat/ 64.png,
json1Code: fr
},
{
json1Language:西班牙语,
json1Icon: https://www.countryflags.io/es/flat/ 64.png,
json1Code: es
}
]
’’;

return Future.value(json1FromJson(jsonString));
}
}

类Json2Page3扩展了StatefulWidget {
@override
_Json2Page3State createState()=> _Json2Page3State();
}

class _Json2Page3State扩展了State< Json2Page3> {
List< Json2> json2 = [];
List< String> _continent = [];
@override
void initState(){
super.initState();
setState((){
Json2Services.getData()。then((data){
setState((){
json2 = data;
_continent =
json2.map< String>(((x)=> x.json2Continent).toSet()。toList();
});
});
});
}

@override
小部件构建(BuildContext上下文){
return DefaultTabController(
长度:_continent.length,
子代:脚手架(
appBar:AppBar(
标题:Text('Page 2'),
底部:TabBar(
制表符:
_continent.map((字符串名称)= > Tab(text:name).toList()),
),
正文:TabBarView(
子级:_continent.map((String name){
return ShowContinent (
json2:List< Json2> .from(json2)
..retainWhere((e)=> e.json2Continent == name),
);
}) .toList()),
));
}
}

类ShowContinent扩展了StatefulWidget {
final List< Json2> json2;
ShowContinent({this.json2});
@override
_ShowContinentState createState()=> _ShowContinentState(json2);
}

类_ShowContinentState扩展了State< ShowContinent> {
final List< Json2> json2;
List< Json1> json1 = [];

_ShowContinentState(this.json2);

bool isLoading = true;
@override
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
Json1Services.getData()。then((data){
setState((){
json1 = data;
isLoading = false;
});
});
});
}

@override
小部件构建(BuildContext上下文){
return isLoading
吗? Center(child:CircularProgressIndicator())
:Column(
child:[
for(json2中的Json2 j2)
Row(
mainAxisAlignment:MainAxisAlignment.spaceAround,
个孩子:[
Text(j2.json2Country.toUpperCase()),
for(int i = 0; i< j2.json2Language.length; i ++)
Builder(
builder:(_){
int index = json1.indexWhere(
(e)=> e.json1Language == j2.json2Language [i]);
返回Row(
个孩子:[
Image.network(json1 [index] .json1Icon),
Text(json1 [index] .json1Code),
],
);
},

],
),
],
);
}
}

void main(){
runApp(MyApp());
}

类MyApp扩展了StatelessWidget {
@override
Widget build(BuildContext context){
return MaterialApp(
title:'Flutter演示',
主题:ThemeData(
primarySwatch:Colors.blue,
visualDensity:VisualDensity.adaptivePlatformDensity,
),
主页:Json2Page3(),
);
}
}


I have 2 JSON file like this:

json1 (API):

[
  {
    "json1Language": "English",
    "json1Icon": "https://www.countryflags.io/gb/flat/64.png",
    "json1Code": "en"
  },
  {
    "json1Language": "French",
    "json1Icon": "https://www.countryflags.io/fr/flat/64.png",
    "json1Code": "fr"
  },
  {
    "json1Language": "Spanish",
    "json1Icon": "https://www.countryflags.io/es/flat/64.png",
    "json1Code": "es"
  }
]

json2 (API):

[
  {
    "json2Country": "Canada",
    "json2Continent": "North American",
    "json2Language": [
      "French",
      "English"
    ]
  },
  {
    "json2Country": "Mexico",
    "json2Continent": "North American",
    "json2Language": [
      "Spanish",
      "English"
    ]
  },
  {
    "json2Country": "United Kingdom",
    "json2Continent": "Europe",
    "json2Language": [
      "English"
    ]
  },
  {
    "json2Country": "France",
    "json2Continent": "Europe",
    "json2Language": [
      "French"
    ]
  },
  {
    "json2Country": "Spain",
    "json2Continent": "Europe",
    "json2Language": [
      "Spanish"
    ]
  }
]

I tried to show the data of json1Code from Json1, it shows an error Flutter: RangeError (index): Invalid value: Valid value range is empty: -1 for a few seconds then shows the data correctly, I'm not sure where I did wrong

I think maybe something wrong in the Build class:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following RangeError was thrown building Builder(dirty):
RangeError (index): Invalid value: Valid value range is empty: -1

The relevant error-causing widget was:
  Builder file:///D:/Flutter/Test/load_data/lib/json2_page3.dart:80:17
When the exception was thrown, this was the stack:
#0      List.[] (dart:core-patch/growable_array.dart:177:60)
#1      _ShowContinentState.build.<anonymous closure> (package:load_data/json2_page3.dart:83:38)
#2      Builder.build (package:flutter/src/widgets/basic.dart:7183:48)
#3      StatelessElement.build (package:flutter/src/widgets/framework.dart:4644:28)
#4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4570:15)

please help me, this is main file

import 'package:flutter/material.dart';
import 'package:load_data/model/json2_model.dart';
import 'package:load_data/service/json1_service.dart';
import 'package:load_data/service/json2_service.dart';
import 'model/json1_model.dart';

class Json2Page3 extends StatefulWidget {
  @override
  _Json2Page3State createState() => _Json2Page3State();
}

class _Json2Page3State extends State<Json2Page3> {
  List<Json2> json2 = [];
  List<String> _continent = [];
  @override
  void initState() {
    super.initState();
    setState(() {
      Json2Services.getData().then((data) {
        setState(() {
          json2 = data;
          _continent = json2.map<String>((x) => x.json2Continent).toSet().toList();
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: _continent.length,
        child: Scaffold(
          appBar: AppBar(
            title: Text('Page 2'),
            bottom: TabBar(tabs: _continent.map((String name) => Tab(text: name)).toList()),
          ),
          body: TabBarView(
              children: _continent.map((String name) {
            return ShowContinent(
              json2: List<Json2>.from(json2)..retainWhere((e) => e.json2Continent == name),
            );
          }).toList()),
        ));
  }
}

class ShowContinent extends StatefulWidget {
  final List<Json2> json2;
  ShowContinent({this.json2});
  @override
  _ShowContinentState createState() => _ShowContinentState(json2);
}

class _ShowContinentState extends State<ShowContinent> {
  final List<Json2> json2;
  List<Json1> json1 = [];

  _ShowContinentState(this.json2);

  @override
  void initState() {
    super.initState();
    Json1Services.getData().then((data) {
      setState(() {
        json1 = data;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        for (Json2 j2 in json2)
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Text(j2.json2Country.toUpperCase()),
              for (int i = 0; i < j2.json2Language.length; i++)
                Builder(
                  builder: (_) {
                    int index = json1.indexWhere((e) => e.json1Language == j2.json2Language[i]);
                    return Row(
                      children: [
                        Image.network(json1[index].json1Icon),
                        Text(json1[index].json1Code),
                      ],
                    );
                  },
                )
            ],
          ),
      ],
    );
  }
}


解决方案

You can copy paste run full code below
You can use addPostFrameCallback and bool isLoading to check loading status
when isLoading == true, return CircularProgressIndicator()
code snippet

bool isLoading = true;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Json1Services.getData().then((data) {
        setState(() {
          json1 = data;
          isLoading = false;
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return isLoading
        ? Center(child: CircularProgressIndicator())
        : Column(

working demo

full code

import 'package:flutter/material.dart';

import 'dart:convert';

List<Json2> json2FromJson(String str) =>
    List<Json2>.from(json.decode(str).map((x) => Json2.fromJson(x)));

String json2ToJson(List<Json2> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

List<Json1> json1FromJson(String str) =>
    List<Json1>.from(json.decode(str).map((x) => Json1.fromJson(x)));

String json1ToJson(List<Json1> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Json1 {
  Json1({
    this.json1Language,
    this.json1Icon,
    this.json1Code,
  });

  String json1Language;
  String json1Icon;
  String json1Code;

  factory Json1.fromJson(Map<String, dynamic> json) => Json1(
        json1Language: json["json1Language"],
        json1Icon: json["json1Icon"],
        json1Code: json["json1Code"],
      );

  Map<String, dynamic> toJson() => {
        "json1Language": json1Language,
        "json1Icon": json1Icon,
        "json1Code": json1Code,
      };
}

class Json2 {
  Json2({
    this.json2Country,
    this.json2Continent,
    this.json2Language,
  });

  String json2Country;
  String json2Continent;
  List<String> json2Language;

  factory Json2.fromJson(Map<String, dynamic> json) => Json2(
        json2Country: json["json2Country"],
        json2Continent: json["json2Continent"],
        json2Language: List<String>.from(json["json2Language"].map((x) => x)),
      );

  Map<String, dynamic> toJson() => {
        "json2Country": json2Country,
        "json2Continent": json2Continent,
        "json2Language": List<dynamic>.from(json2Language.map((x) => x)),
      };
}

class Json2Services {
  static Future<List<Json2>> getData() async {
    await Future.delayed(Duration(seconds: 5), () {});

    String jsonString = '''
    [
  {
    "json2Country": "Canada",
    "json2Continent": "North American",
    "json2Language": [
      "French",
      "English"
    ]
  },
  {
    "json2Country": "Mexico",
    "json2Continent": "North American",
    "json2Language": [
      "Spanish",
      "English"
    ]
  },
  {
    "json2Country": "United Kingdom",
    "json2Continent": "Europe",
    "json2Language": [
      "English"
    ]
  },
  {
    "json2Country": "France",
    "json2Continent": "Europe",
    "json2Language": [
      "French"
    ]
  },
  {
    "json2Country": "Spain",
    "json2Continent": "Europe",
    "json2Language": [
      "Spanish"
    ]
  }
]
    ''';

    return Future.value(json2FromJson(jsonString));
  }
}

class Json1Services {
  static Future<List<Json1>> getData() async {
    await Future.delayed(Duration(seconds: 5), () {});
    String jsonString = '''
    [
  {
    "json1Language": "English",
    "json1Icon": "https://www.countryflags.io/gb/flat/64.png",
    "json1Code": "en"
  },
  {
    "json1Language": "French",
    "json1Icon": "https://www.countryflags.io/fr/flat/64.png",
    "json1Code": "fr"
  },
  {
    "json1Language": "Spanish",
    "json1Icon": "https://www.countryflags.io/es/flat/64.png",
    "json1Code": "es"
  }
]
    ''';

    return Future.value(json1FromJson(jsonString));
  }
}

class Json2Page3 extends StatefulWidget {
  @override
  _Json2Page3State createState() => _Json2Page3State();
}

class _Json2Page3State extends State<Json2Page3> {
  List<Json2> json2 = [];
  List<String> _continent = [];
  @override
  void initState() {
    super.initState();
    setState(() {
      Json2Services.getData().then((data) {
        setState(() {
          json2 = data;
          _continent =
              json2.map<String>((x) => x.json2Continent).toSet().toList();
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: _continent.length,
        child: Scaffold(
          appBar: AppBar(
            title: Text('Page 2'),
            bottom: TabBar(
                tabs:
                    _continent.map((String name) => Tab(text: name)).toList()),
          ),
          body: TabBarView(
              children: _continent.map((String name) {
            return ShowContinent(
              json2: List<Json2>.from(json2)
                ..retainWhere((e) => e.json2Continent == name),
            );
          }).toList()),
        ));
  }
}

class ShowContinent extends StatefulWidget {
  final List<Json2> json2;
  ShowContinent({this.json2});
  @override
  _ShowContinentState createState() => _ShowContinentState(json2);
}

class _ShowContinentState extends State<ShowContinent> {
  final List<Json2> json2;
  List<Json1> json1 = [];

  _ShowContinentState(this.json2);

  bool isLoading = true;
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Json1Services.getData().then((data) {
        setState(() {
          json1 = data;
          isLoading = false;
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return isLoading
        ? Center(child: CircularProgressIndicator())
        : Column(
            children: [
              for (Json2 j2 in json2)
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    Text(j2.json2Country.toUpperCase()),
                    for (int i = 0; i < j2.json2Language.length; i++)
                      Builder(
                        builder: (_) {
                          int index = json1.indexWhere(
                              (e) => e.json1Language == j2.json2Language[i]);
                          return Row(
                            children: [
                              Image.network(json1[index].json1Icon),
                              Text(json1[index].json1Code),
                            ],
                          );
                        },
                      )
                  ],
                ),
            ],
          );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Json2Page3(),
    );
  }
}

这篇关于Flutter:RangeError(索引):无效值:有效值范围为空:-1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-15 03:42