Flutter: 尝试将值传递给另一个类时出错

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

Flutter: Error trying to pass a value to another class

问题

我正在尝试将一个值(我的ListView.builder的当前索引号)传递给另一个函数。但是我遇到了以下错误:

════════ 异常信息来自widgets库 ═══════════════════════════════════ 抛出了以下RangeError,构建了BookFeederSearch(dirty,dependencies: [_InheritedProviderScope<UserProvider?>],state: BookFeederSearchState#3217f):RangeError(索引):无效值:有效值范围为空:0

请看我的代码:

class Search2 extends StatefulWidget {
  static const String id = 'Search2';
  const Search2({super.key});

  @override
  State<Search2> createState() => _Search2State();
}

class _Search2State extends State<Search2> {
  // ...(省略其他代码)

  Expanded(
    child: ListView.builder(
      itemCount: _resultList.length,
      itemBuilder: ((context, index) {
        return Align(
          alignment: Alignment.topCenter,
          // this will have the folders overlap each other (set to 0.5)
          heightFactor: 0.2,
          child: Column(
            children: [
              // ...(省略其他代码)
              InkWell(
                onTap: () {
                  //导航到下一个页面(显示文件夹)并传递索引号
                  final indexPage = index;
                  print('$indexPage, 打开文件夹');

                  Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (context) =>
                          BookFeederSearch(indexPage),
                    ),
                  );
                },
                // ...(省略其他代码)
              ),
            ],
          ),
        );
      }),
    ),
  );
  // ...(省略其他代码)
}

我无法确定导致此问题的原因。我已通过打印值来检查,但它确实获取了正确的输入。我以前在不同的类中传递过值,没有问题,但在ListView.builder中无法传递。所以我猜测这可能是问题的原因,但找不到解决方法。非常感谢您的帮助。

英文:

I am trying to pass a value (the current index number of my ListView.builder) to another function. However I get the following error:

════════ Exception caught by widgets library ═══════════════════════════════════ The following RangeError was thrown building BookFeederSearch(dirty, dependencies: [_InheritedProviderScope<UserProvider?>], state: BookFeederSearchState#3217f): RangeError (index): Invalid value: Valid value range is empty: 0

Please see my code:

class Search2 extends StatefulWidget {
  static const String id = &#39;Search2&#39;;
  const Search2({super.key});

  @override
  State&lt;Search2&gt; createState() =&gt; _Search2State();
}

class _Search2State extends State&lt;Search2&gt; {
  bool _addToLibrary = false;


  List _allResults = [];
  List _resultList = [];

  final TextEditingController _searchController = TextEditingController();

  @override
  void initState() {
    _searchController.addListener(_onSearchChanged);
    //getClientStream();
    super.initState();
  }

  _onSearchChanged() {
    print(_searchController.text);
    searchResultList();
  }

  searchResultList() {
    var showResults = [];
    if (_searchController.text != &quot;&quot;) {
      for (var clientSnapShot in _allResults) {
        var name = clientSnapShot[&#39;TitleEnglish&#39;].toString().toLowerCase();
        if (name.contains(_searchController.text.toLowerCase())) {
          showResults.add(clientSnapShot);
        }
      }
    } else {
      showResults = List.from(_allResults);
    }
    setState(() {
      _resultList = showResults;
    });
  }

  getClientStream() async {
    var data = await FirebaseFirestore.instance
        .collection(&#39;Books&#39;)
        .orderBy(&#39;TitleEnglish&#39;)
        .get();
    setState(() {
      _allResults = data.docs;
    });
    searchResultList();
  }

  @override
  void dispose() {
    _searchController.removeListener(_onSearchChanged);
    _searchController.dispose();
    super.dispose();
  }

  @override
  void didChangeDependencies() {
    getClientStream();
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    final User? user = Provider.of&lt;UserProvider&gt;(context).getUser;
    return Scaffold(
      appBar: AppBar(
        leadingWidth: 120,
        backgroundColor: const Color(
          (0XFF293D63),
        ),
        leading: IconButton(
          onPressed: () {
            //print(&#39;Go Back Pressed&#39;);
            Navigator.pop(context);
          },
          icon: SvgPicture.asset(&#39;images/button_goback_clean_svg.svg&#39;),
        ),
        title: const Text(
          &#39;SEARCH&#39;,
          style: TextStyle(
            fontFamily: &#39;Sigmar&#39;,
            fontSize: 20.0,
          ),
        ),
        centerTitle: true,
      ),
      //below links to history_book.dart
      //SingleChildScrollView avoids keyboard overflow
      body: Column(
        // crossAxisAlignment: CrossAxisAlignment.center,
        // mainAxisSize: MainAxisSize.max,
        // mainAxisAlignment: MainAxisAlignment.end,
        children: [
          Container(
            height: 50,
            width: 500,
            padding: const EdgeInsets.symmetric(horizontal: 20),
            decoration: BoxDecoration(
              // color: Color(0xFF5F94AF),
              color: Colors.blue[100],
              // border: Border.all(width: 10, color: Colors.white),

              borderRadius: const BorderRadius.only(
                bottomLeft: Radius.circular(30.0),
                bottomRight: Radius.circular(30.0),
              ),
            ),
            child: CupertinoSearchTextField(
              //done with opacity so it has no colour
              backgroundColor: Colors.white.withOpacity(0),
              controller: _searchController,
              placeholder: &#39;Search for book title&#39;,

              style: const TextStyle(
                fontFamily: &#39;NotoBold&#39;,
                fontSize: 15.0,
                color: Color((0XFF293D63)),
              ),
            ),
          ),
          Expanded(
            child: ListView.builder(
              //scrollDirection: Axis.horizontal,
              itemCount: _resultList.length,
              itemBuilder: ((context, index) {
                return Align(
                  alignment: Alignment.topCenter,
                  // this will have the folders overlap each other (set to 0.5)
                  heightFactor: 0.2,
                  child: Column(
                    children: [
                      Container(
                        height: 20,
                      ),
                      Row(
                        children: [
                          Container(
                            width: 200,
                          ),
                          Container(
                            width: 400,
                            height: 40,
                            decoration: BoxDecoration(
                              // color: Color(0xFF5F94AF),
                              color: Colors.blue[100],
                              // border: Border.all(width: 10, color: Colors.white),

                              borderRadius: const BorderRadius.only(
                                topLeft: Radius.circular(30.0),
                                topRight: Radius.circular(30.0),
                              ),
                            ),
                            alignment: Alignment.centerLeft,
                            padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
                            child: InkWell(
                              onTap: () {
                                //To navigate to the next page (shows folder) and pass in the index numbers
                                final indexPage = index;
                                print(&#39;$indexPage, Open Folder&#39;);

                                Navigator.of(context).push(
                                  MaterialPageRoute(
                                    builder: (context) =&gt;
                                        BookFeederSearch(indexPage),
                                  ),
                                );
                              },

I am unable to figure out what seems to cause this problem. I have checked by printing values, but it does get the correct input. I have passed values to other classes before without an issue but not while in a ListView.builder. So I am guessing this is causing the problem, but cannot find the solution. Much appreciated for your help.

答案1

得分: 0

以下是您要求的翻译内容:

您遇到的错误可能是因为您将 index 值传递给 BookFeederSearch 构造函数的方式不正确。不应该直接在 ListView.builderitemBuilder 中访问 BuildContext context 变量。相反,您可以使用 Builder 小部件在 itemBuilder 内部创建一个新的 BuildContext

以下是您可以修改代码以避免此问题的方式:

ListView.builder(
  itemCount: _resultList.length,
  itemBuilder: (context, index) {
    return Builder(
      builder: (innerContext) {
        return Align(
          // ... 其余代码 ...
          InkWell(
            onTap: () {
              final indexPage = index;
              print('$indexPage, 打开文件夹');

              Navigator.of(innerContext).push(
                MaterialPageRoute(
                  builder: (context) => BookFeederSearch(indexPage),
                ),
              );
            },
            // ... 其余代码 ...
          ),
        );
      },
    );
  },
)

通过使用 Builder 小部件,您在 itemBuilder 内部创建了一个新的 BuildContext,这应该解决您遇到的问题。确保在导航到 BookFeederSearch 屏幕时使用 innerContext

英文:

The error you're encountering might be due to the way you're passing the index value to the BookFeederSearch constructor. The BuildContext context variable should not be directly accessed inside the itemBuilder of the ListView.builder. Instead, you can use a Builder widget to create a new BuildContext within the itemBuilder.

Here's how you can modify your code to avoid the issue:

ListView.builder(
  itemCount: _resultList.length,
  itemBuilder: (context, index) {
    return Builder(
      builder: (innerContext) {
        return Align(
          // ... rest of your code ...
          InkWell(
            onTap: () {
              final indexPage = index;
              print(&#39;$indexPage, Open Folder&#39;);

              Navigator.of(innerContext).push(
                MaterialPageRoute(
                  builder: (context) =&gt; BookFeederSearch(indexPage),
                ),
              );
            },
            // ... rest of your code ...
          ),
        );
      },
    );
  },
)

By using the Builder widget, you create a new BuildContext within the itemBuilder, which should resolve the issue you're facing. Make sure to use the innerContext when navigating to the BookFeederSearch screen.

答案2

得分: 0

错误消息表明有效值范围为空,意味着您传递的索引值超出了范围。

可能的原因是在使用 Navigator.of(context).push 推送路由时未提供 BookFeederSearch 小部件的键。

尝试更新 onTap 处理程序,将 index 作为 key 传递给 BookFeederSearch 小部件:

import 'package:flutter/foundation.dart';
//...
child: InkWell(
  onTap: () {
    final indexPage = index;
    print('$indexPage, 打开文件夹');

    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) =>
            BookFeederSearch(key: ValueKey<int>(index), indexPage: indexPage),
      ),
    );
  },
  // 剩余的代码...

还要更新 BookFeederSearch 小部件以接收 indexPage 参数:

class BookFeederSearch extends StatefulWidget {
  // 在构造函数中添加 'indexPage' 参数
  final int indexPage;
  BookFeederSearch({Key? key, required this.indexPage}) : super(key: key);
  //...
}
英文:

The error message indicates that the valid value range is empty, meaning the index value you are passing is out of range.

The reason might be that you are not providing a key to the BookFeederSearch widget when pushing the route using Navigator.of(context).push.

Try to update the onTap handler to pass the index as a key to the BookFeederSearch widget:

import &#39;package:flutter/foundation.dart&#39;;
//...
child: InkWell(
  onTap: () {
    final indexPage = index;
    print(&#39;$indexPage, Open Folder&#39;);

    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) =&gt;
            BookFeederSearch(key: ValueKey&lt;int&gt;(index), indexPage: indexPage),
      ),
    );
  },
  // Rest of your code...

Update also the BookFeederSearch widget to receive the indexPage parameter:

class BookFeederSearch extends StatefulWidget {
  // Add the &#39;indexPage&#39; parameter to the constructor
  final int indexPage;
  BookFeederSearch({Key? key, required this.indexPage}) : super(key: key);
  //...
}

huangapple
  • 本文由 发表于 2023年8月4日 22:35:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76836901.html
匿名

发表评论

匿名网友

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

确定