微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flutter在ListView中不显示有状态子控件

如何解决Flutter在ListView中不显示有状态子控件

就像在标题中一样,我在使用ListView时遇到问题,希望您能为我提供帮助。

我正在使用基本的ListView来构建“卡小部件”(具有其自身的状态)。 ListView使用ID列表,这些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]。这里发生了什么?我想念什么吗?

解决方法

您的CRD小部件是一个StatefulWidget,并且在重建时将重用该状态,因为该小部件的类型相同且您未为其提供密钥。

要解决您的问题,有几种可能性:

  1. 向列表中的所有项目添加密钥
  2. 在您的小部件状态下实施didUpdateWidget方法
  3. 使用无状态组件,并在构建方法中进行字符串隐藏

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。