代码之家  ›  专栏  ›  技术社区  ›  rozerro

李斯特里被解雇后的意外行为

  •  0
  • rozerro  · 技术社区  · 5 年前

    在一个页面上,我有一个包含ListEntry元素的ListView。 ListEntry是一个statefull,并且有一个属性\u可见,默认为false。 有一种方法_onLeadingPressed允许反转可见属性——它没有问题。 每一个倾听者都是可以被忽视的,所以我可以忽略它。

    class ListEntry extends StatefulWidget {
      @override
      _ListEntryState createState() => _ListEntryState();
    }
    
    class _ListEntryState extends State<ListEntry> {
      bool _visible = false;
    
      // there is an option to change `_visible` for every `ListEntry`
      void _onLeadingPressed() {
        setState(() {
          _visible = !_visible;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Dismissible(
          key: UniqueKey(),
          direction: DismissDirection.horizontal,
          onDismissed: (direction) async {
            _visible = false;
            // some action here
          },
          child: ListTile(
            //every ListTile has a logic to show some info based on `_visible` value
            ...
          ),
        );
      }
    }
    

    现在是有趣的部分。 例如,当前列表视图包含以下元素:

    • ListEntry 1(_visible=false)
    • ListEntry 2(_visible=true)
    • ListEntry 3(_visible=false)

    让我们忽略ListEntry 1。现在列表视图显示如下:

    • ListEntry 2(_visible=false)
    • ListEntry 3(_visible=true)

    为什么ListEntry 3为真,而ListEntry 2也为假? 排除第一要素后不应该是这样吗?

    • ListEntry 2(_visible=true)
    • ListEntry 3(_visible=false)
    0 回复  |  直到 5 年前
        1
  •  1
  •   Morez    5 年前

    我认为你面临的问题是钥匙。当你打电话的时候 setState ,将生成新的唯一密钥并将其分配给ListEntry,而Flatter在其元素树中找不到任何具有该密钥的小部件,因此可能会出现这种行为。

    尝试使用特定于该ListEntry的内容作为键,例如名称、标题或任何特定于该ListEntry的内容,以便在调用 设定状态 ,您不生成新的uniqueKey,但使用上一个,Flatter可以找到与具有相同密钥的小部件匹配的状态。这将保持状态不变,并显示正确的值。

    结账 this 《颤振无聊秀》的一部分也有同样的问题 this tutorial .