Flutter 在 ListView 中不显示有状态的子 Widget
Posted
技术标签:
【中文标题】Flutter 在 ListView 中不显示有状态的子 Widget【英文标题】:Flutter does not display stateful children Widget in ListView 【发布时间】:2021-02-07 10:49:07 【问题描述】:如标题所示,我对 ListView 有疑问,希望您能帮帮我。
我正在使用基本的 ListView 来构建“卡片小部件”(具有自己的状态)。 ListView 使用一个 Id 列表,用于构建那些“卡片小部件”
问题: 每当我通过删除 Id 从列表中删除卡片时,ListView 总是会删除最顶部的子小部件。我的后端删除了正确的内容,因为在我重新启动应用程序以便重新填充页面后,已删除的卡片实际上已被删除,而被 ListView 删除的卡片再次可见。似乎 ListView 没有重绘它的孩子。有什么想法吗?
我创建了基本的 DartPad 代码来说明问题
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
class MyHomePage extends StatefulWidget
MyHomePage(Key key, this.title) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
int _counter = 0;
List<String> dd = new List<String>();
@override
void initState()
super.initState();
dd.add('A');
dd.add('B');
dd.add('C');
dd.add('D');
void _incrementCounter()
setState(()
_counter++;
dd.insert(1, 'Q');
);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title + _counter.toString()),
),
body: ListView.builder(
addAutomaticKeepAlives: false,
itemBuilder: (context, index)
print('calling: $index :' + _counter.toString() + ' -> ' + dd[index] );
return new CRD(title: dd[index]);
,
itemCount: dd.length
),
/*
ListView(
children: dd.map((str)
return CRD(title: str);
).toList()
),
*/
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
class CRD extends StatefulWidget
CRD(Key key, this.title) : super(key: key);
final String title;
@override
_CRD createState() => _CRD();
class _CRD extends State<CRD>
String _val;
@override
void initState()
super.initState();
_val = widget.title + ' ' + widget.title;
@override
Widget build(BuildContext context)
return Text(_val);
因此,单击一次添加按钮后,列表内容为 [A,Q,B,C,D],但应用程序显示 [A,B,C,D,D]。这里发生了什么?我错过了什么吗?
【问题讨论】:
【参考方案1】:您的 CRD 小部件是 StatefulWidget,并且在重建时将重用该状态,因为小部件的类型与您未给它键的类型相同。
要解决您的问题,有几种可能性:
-
为列表中的所有项目添加一个键
在您的小部件状态中实现
didUpdateWidget
方法
使用无状态小部件并在构建方法中进行字符串连接
【讨论】:
好的,所以基本上我根据我的小部件实例在“didUpdateWidget”中填充我的小部件状态?我需要这样做,因为底层状态被重用而不是再次创建。那正确吗?实施“didUpdateWidget”得到了我预期的结果!谢谢! 好吧,部分是的,didUpdateWidgetbis 仅在重建时才调用,因此您还需要在 initState 中执行此操作 好的,非常感谢!添加密钥似乎是我想做的最简单的事情。祝你有美好的一天:)以上是关于Flutter 在 ListView 中不显示有状态的子 Widget的主要内容,如果未能解决你的问题,请参考以下文章
Flutter ListView scrollPhysics 在 SingleChildScrollView 中不起作用
Flutter—ListView嵌套ListView不显示的问题