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

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

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:

确定