Flutter新闻APP点击搜索文章触发RangeError(index)问题求助
问题分析与解决
错误根源
你遇到的RangeError (index): Invalid value: Valid value range is empty: 0错误,核心原因是错误引用了从未被赋值的空列表_searchedPost:
_searchedPost初始化后一直是空列表,没有任何数据填充;- 实际展示搜索结果的是
_searchedArticles列表,点击时却试图访问_searchedPost[i],自然触发索引越界错误。
修复步骤
1. 移除无用变量
删除_SearchBarState中未使用的_searchedPost变量:
// 删掉这行 final List _searchedPost = [];
2. 修正点击事件的数据源
将InkWell的onTap回调里的_searchedPost[i]替换为_searchedArticles[i],同时可以简化不必要的空判断(因为ListView.builder只会渲染存在的文章,_searchedArticles[i]必然有效):
onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => ArticlePage( data: _searchedArticles[i], ), ), ); },
3. 额外优化(可选)
为避免嵌套Map访问时可能出现的空指针问题,给_searchedArticles[i]["_embedded"]这类嵌套访问添加空安全判断:
// 替换原图片加载代码 _searchedArticles[i]["_embedded"]?["wp:featuredmedia"]?.isNotEmpty == true ? Image.network( _searchedArticles[i]["_embedded"]["wp:featuredmedia"][0]["link"], width: double.infinity, height: 220, fit: BoxFit.cover, ) : const Text("Nessuna immagine caricata"),
修复后的完整_SearchBarState代码
class _SearchBarState extends State<SearchBar> { late List _searchedArticles = []; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: TextField( style: const TextStyle(color: Colors.white), decoration: const InputDecoration( hintText: "Cerca Articolo", hintStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.w500), border: InputBorder.none, ), onChanged: (val) { setState(() { _searchedArticles = widget.posts.where((element) { return element["title"]["rendered"].contains(val); }).toList(); }); }, ), ), body: _searchedArticles.isEmpty ? Scaffold( backgroundColor: Colors.white, body: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( "assets/images/search-illustration.png", height: 230, ), const SizedBox( height: 20, ), const Text( 'Nessun articolo trovato!', style: TextStyle( fontSize: 20.0, color: Colors.black, fontFamily: "Raleway", fontWeight: FontWeight.w600, ), ), const SizedBox( height: 20, ), const Text( 'Inserisci meglio le lettere o parole chiave dell’articolo che stai cercando e riprova.', textAlign: TextAlign.center, style: TextStyle( fontSize: 16.0, color: Colors.black54, fontFamily: "Raleway", fontWeight: FontWeight.w400, ), ), const SizedBox( height: 30, ), MaterialButton( height: 50, elevation: 0, color: Colors.blue[900], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: const [ Text( 'Torna alla home', style: TextStyle( fontSize: 16.0, color: Colors.white, fontFamily: "Raleway", fontWeight: FontWeight.w600), ), ], ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => HomePage(), ), ); }, ), ], ), ), ) : ListView.builder( itemCount: _searchedArticles.length, itemBuilder: (context, i) { return Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ Card( margin: const EdgeInsets.all(10), elevation: 5, shadowColor: Colors.black26, color: Colors.white, child: InkWell( child: ClipRRect( borderRadius: BorderRadius.circular(10), child: Column( mainAxisSize: MainAxisSize.min, children: [ _searchedArticles[i]["_embedded"]?["wp:featuredmedia"]?.isNotEmpty == true ? Image.network( _searchedArticles[i]["_embedded"]["wp:featuredmedia"][0]["link"], width: double.infinity, height: 220, fit: BoxFit.cover, ) : const Text("Nessuna immagine caricata"), Column( children: [ Padding( padding: const EdgeInsets.only( left: 16, top: 16, bottom: 16), child: Row( children: [ Expanded( child: Text( _searchedArticles[i]["title"] ["rendered"] as String, maxLines: 3, overflow: TextOverflow.clip, softWrap: true, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w600, fontFamily: "Raleway", ), ), ), ], ), ) ], ), ], ), ), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => ArticlePage( data: _searchedArticles[i], ), ), ); }, ), ), ], ); }, ), ); } }
内容的提问来源于stack exchange,提问作者Pimpi Rimpà
相关产品推荐
相关产品推荐

