如何解决可增长列表中的范围错误?

huangapple go评论58阅读模式
英文:

How to solve range error in growable list?

问题

在调用getUserById()函数时一切正常,可变字符串工作正常,但当我在文本小部件内使用相同的变量时,它会显示RangeError。问题仅发生在我尝试在build方法内使用名为dataAsString的可变字符串列表时。

以下是错误的代码。转到我已经注释错误行的Scaffold

import 'package:Healthwise/helpers/user.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import '../helpers/backEnd.dart';
import '../helpers/frontEnd.dart';

class ResultPage extends StatefulWidget {
  const ResultPage({Key? key}) : super(key: key);

  @override
  State<ResultPage> createState() => _ResultPageState();
}

class _ResultPageState extends State<ResultPage> {
  String objectToString = '';
  String e = '';
  //这个变量正在创建问题...
  // 我已经尝试使用final而不是var,但没有效果。
  var dataAsString = <String>[];

  @override
  void initState() {
    super.initState();
    getUserById();
  }

  getUserById() {
    final String id = itemName;
    userRef.doc(id).get().then((DocumentSnapshot doc) {
      objectToString = doc.data().toString();
      String temp = '';
      int i = 1;
      bool end = false;
      while (objectToString[i] != '}') {
        if (objectToString[i - 1] == ' ' && objectToString[i - 2] == ':') {
          while (objectToString[i] != ',' && !end) {
            temp += objectToString[i];
            if (objectToString[i + 1] != '}') {
              i++;
            } else {
              end = true;
            }
          }
          dataAsString.add(temp);
          temp = '';
          print("The code below this line prints everything perfectly");
          print(dataAsString.length);
          print(dataAsString[0]);
        }
        i++;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(backgroundColor: primary_color, title: Text("Apple")),
      body: Container(
        child: Column(children: [
          ListTile(
            title: Text(dataAsString[0]),
          ),
          ListTile(
            title: Text(dataAsString[1]),
          ),
          ListTile(
            title: Text(dataAsString[2]),
          ),
        ]),
      ),
    );
  }
}

如何解决可增长列表中的范围错误?

请注意,dataAsString 列表是在getUserById()方法中异步填充的,所以在初始渲染时可能为空,因此需要确保在使用它之前检查其是否为空或添加适当的空处理。

英文:

When I am calling getUserById() function everything works fine and the growable string works fine but when I use the same variable inside a text widget then it shows RangeError.
The problem is occuring only when I try to use a growable list of string named as dataAsString inside the build.

如何解决可增长列表中的范围错误?

Here is the Code with Error. Go to the scaffold where I have commented the line of error

import &#39;package:Healthwise/helpers/user.dart&#39;;
import &#39;package:cloud_firestore/cloud_firestore.dart&#39;;
import &#39;package:flutter/material.dart&#39;;
import &#39;../helpers/backEnd.dart&#39;;
import &#39;../helpers/frontEnd.dart&#39;;
class ResultPage extends StatefulWidget {
const ResultPage({Key? key}) : super(key: key);
@override
State&lt;ResultPage&gt; createState() =&gt; _ResultPageState();
}
class _ResultPageState extends State&lt;ResultPage&gt; {
// String docId = &#39;&#39;;
String objectToString = &#39;&#39;;
String e = &#39;&#39;;
//This variable is creating the problem...
// I have tried this by using a final instead of var, but nothing worked.
var dataAsString = &lt;String&gt;[];
@override
void initState() {
super.initState();
// getUsers();
getUserById();
}
getUserById() {
final String id = itemName;
userRef.doc(id).get().then((DocumentSnapshot doc) {
// final x = doc.data();
// docId= doc.id;
objectToString = doc.data().toString();
String temp = &#39;&#39;;
// print(doc.data());
// print(doc.id);
int i = 1;
// int j = 0;
bool end = false;
//We are just parsing the object into string.
while (objectToString[i] != &#39;}&#39;) {
if (objectToString[i - 1] == &#39; &#39; &amp;&amp; objectToString[i - 2] == &#39;:&#39;) {
while (objectToString[i] != &#39;,&#39; &amp;&amp; end != true) {
// print(z[i]);
temp += objectToString[i];
if (objectToString[i + 1] != &#39;}&#39;) {
i++;
} else {
end = true;
}
}
//Here I add all the strings to list...
// This line works fine.
dataAsString.add(temp);
temp = &#39;&#39;;
// j++;
print(&quot;The code below this line prints everything perfectly&quot;);
print(dataAsString.length);
print(dataAsString[0]);
}
i++;
}
// print(dataAsString[0]);
// print(dataAsString[1]);
// print(&quot;+++++++++++&quot;);
// print(dataAsString[2]);
// for (var k in dataAsString) {
//   print(k);
// }
// print(dataAsString);
// setState(() {});
});
}
// getUsers() {
//   userRef.get().then((QuerySnapshot snapshot) {
//     snapshot.docs.forEach((DocumentSnapshot doc) {
//       print(doc.data());
//       print(doc.id);
//       print(doc.exists);
//     });
//   });
// }
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: primary_color, title: Text(&quot;Apple&quot;)),
body: Container(
child: Column(children: [
ListTile(
//The problem arises here and the app do not crash if I run the same code with just a //string in place of dataAsString[0]
title: Text(dataAsString[0]),
),
ListTile(
title: Text(dataAsString[1]),
),
ListTile(
title: Text(dataAsString[2]),
),
]),
),
);
}
}

答案1

得分: 1

你不能在dataAsString上有数据,因为你正在使用.then来获取数据。你可以进行值检查,如下:

Text(dataAsString.isNotEmpty ? dataAsString[0] : "0 是空的"),
Text(dataAsString.length > 2 ? dataAsString[1] : "1 索引为空"),
Text(dataAsString.length > 3 ? dataAsString[2] : "第三个项目为空"),
英文:

You cant have data on dataAsString because you are using future(.then) on fetching data. You can do value check like

Text( dataAsString.isNotEmpty? dataAsString[0]: &quot;0 is empty&quot;),
Text( dataAsString.length&gt;2? dataAsString[1]: &quot;1 index is empty&quot;),
Text( dataAsString.length&gt;3? dataAsString[2]: &quot;3rd item is empty&quot;),

答案2

得分: 1

因为您的 dataAsString 在第一次渲染 Flutter 时还没有准备好。因此,您需要等待 getUserById 完成以访问 dataAsString 的值。

您可以使用 builder 来以可读的方式检查数据是否准备就绪。

Builder(
  builder: (context) {
    if (dataAsString.length >= 2) {
      return Column(children: [
        ListTile(
          title: Text(dataAsString[0]),
        ),
        ListTile(
          title: Text(dataAsString[1]),
        ),
        ListTile(
          title: Text(dataAsString[2]),
        ),
      ]);
    } else {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
  },
),

警告:这将有效,因为在完成异步任务后,您调用了 setState

英文:

It's cause your dataAsString ins't ready on first Flutter rendered frame. So, you need to wait for the getUserById finish to access the dataAsString values.

You can use a builder to check if the data is ready in a readable way.

Builder(
  builder: (context) {
    if (dataAsString.length &gt;= 2) {
      return Column(children: [
        ListTile(
          title: Text(dataAsString[0]),
        ),
        ListTile(
          title: Text(dataAsString[1]),
        ),
        ListTile(
          title: Text(dataAsString[2]),
        ),
      ]);
    } else {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
  },
),

Warning: it'll work cause you're calling setState when you finish the async task.

huangapple
  • 本文由 发表于 2023年2月16日 04:31:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75465167.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定