【问题标题】:Widgets in a ListView losing state while scrolling Flutter滚动 Flutter 时 ListView 中的小部件丢失状态
【发布时间】:2018-11-13 08:08:34
【问题描述】:

我从网络(世界杯比赛)获取 JSON 并用它构建一个 ListView。

Widget build(BuildContext context) {
return new Material(
  child: _isLoading
      ? new Center(child: new CircularProgressIndicator())
      : new ListView.builder(
          itemCount: matches != null ? matches["jogos"].length : 0,
          itemBuilder: (BuildContext context, int index) {
            GameBetCard actualGameBetCard = new GameBet(
              homeTeamName: matches["jogos"][index]["m_clube"],
              awayTeamName: matches["jogos"][index]["v_clube"],
              homeTeamId: matches["jogos"][index]["id_clubem"],
              awayTeamId: matches["jogos"][index]["id_clubev"],
              date: matches["jogos"][index]["data"] +
                  " - " +
                  matches["jogos"][index]["hora"],
              stage: Stage.groups,
              groupName: matches["jogos"][index]["nome_grupo"],
              scoreHomeBet: "",
              scoreAwayBet: "",
              scoreHome: matches["jogos"][index]["placarm_tn"],
              scoreAway: matches["jogos"][index]["placarv_tn"],
            ).gameBetCard;
            _addGameBetToList(actualGameBetCard);
            return actualGameBetCard;
          },
        ),
);}

我在 GameBetCard 中有 2 个 TextFormFields,当我在其中插入一些东西时,向下滚动并再次向上滚动卡片会再次启动,而 TextFormField 中没有我的数据。另一件事,我有一个按钮,单击它时它会插入到 firebase 数据库,然后它完成了我更改了 Check 图标的图标,但在 TextFormField 的相同情况下,它会在它超出“屏幕范围”时重新启动

ps:我在调试时看到 ListView 只渲染将出现在屏幕上的元素。当它出来时,它被处理掉了。返回时默认再次启动。

我该如何处理?我希望它保存我的小部件的状态。

【问题讨论】:

  • 给你的ListView一个PageStorageKey
  • 嗯,我会搜索一下!

标签: listview widget flutter


【解决方案1】:

您的 TextFormField 需要有自己的 TextEditingController。

这些 TextEditingController 应该位于顶部的 Widget(包含 ListView 的那个)。如果你不这样做,TextEditingController 也会在单个小部件被销毁/重新创建时被销毁/重新创建。

在顶部创建两个 TextEditingController 并将它们传递给您的 GameBet 小部件,然后将它们设置为里面的 TextFormFields。

此外,顶部的 Widget 应该是有状态的 Widget,这样控制器在重建 Widget 时不会被破坏。最后,您还应该处置控制器。

看这个例子:

class MyForm extends StatefulWidget {
  @override
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> {
  TextEditingController _controller1, _controller2;

  @override
  void initState() {
    super.initState();
    _controller1 = new TextEditingController();
    _controller2 = new TextEditingController();
  }

  @override
  void dispose() {
    super.dispose();
    _controller1.dispose();
    _controller2.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Material(
      child: ListView.builder(
        itemCount: count,
        itemBuilder: (BuildContext context, int index) {
          return GameBet(
            controller1: _controller1,
            controller2: _controller2,
            // rest of fields
          );
        },
      ),
    );
  }
}

然后,在您的 GameBet 中,记得设置控制器:

TextFormField(
  controller: _controller1,
)

【讨论】:

    猜你喜欢
    • 2021-06-27
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 2017-10-25
    • 2018-06-03
    • 1970-01-01
    • 2021-01-14
    相关资源
    最近更新 更多