当onPressed按钮时如何从ListView中删除TextField? [英] How to remove a TextField from ListView when onPressed button?

查看:82
本文介绍了当onPressed按钮时如何从ListView中删除TextField?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户单击清除图标按钮时,如何删除TextField? (不仅清除TextField的文本)

How to remove the TextField when user click on "clear icon" button ? (not just clear the Text of TextField)

用户故事

用户单击按钮以添加播放器。 (从技术上讲,此按钮添加TextField)

用户可以在TextField上写入播放器的名称。

用户单击清除图标按钮以删除当前的TextField(与add相反)。功能)。

User Story
The user click on a button to add player. (Technically this button add TextField)
The user can write the name of player on TextField.
The user click on a "clear icon" button to remove current TextField (opposite of add function).

new ListView.builder(
                     padding: EdgeInsets.all(0),
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      itemCount: 5,
                      itemBuilder: (context, index) {
                        print(index);
                        return TextField(
                          maxLength: 20,
                          decoration: InputDecoration(
                            labelText: "Player ${index+1}",
                            counterText: "",
                            prefixIcon: const Icon(Icons.person),
                            suffixIcon: new IconButton(
                                icon: Icon(Icons.clear),
                                onPressed: () =>
                                  setState(() {
                                    this.dispose(); // -----Doesn't work----
                                  })
                                ),
                          ),
                        );
                      }
                    ),

例如,用户在播放器上设置了 John 4.如果用户单击清除按钮,则删除了Player 4 TextField。它将仅保留4个TextField

For example, user set "John" on Player 4 if user click on "clear button" then Player 4 TextField is deleted. It will remain only 4 TextField

< img src = https://i.stack.imgur.com/pxoJe.png alt =在此处输入图片描述>

推荐答案

我认为的事实


  1. 您希望能够删除(或添加(从)列表中的字段

  2. 您希望在删除字段时保留其余字段的值

  3. 列表可以大于5

解决方案:

如果您希望以上所有内容均成立,那么实际上您需要跟踪TextFields的 TextEditingController s,而不是文本字段本身。这是因为TextField的值实际上存储在TextEditingController中(如果不为每个窗口小部件提供它,则会动态创建)。检查一下:

If you want all the above to be true, then you actually need to track the TextEditingControllers of the TextFields, instead of the text fields themselves. This is because the value of the TextField is actually stored in the TextEditingController (which is created anew on the fly if you do not supply it for each widget). Check this out:

import 'package:flutter/material.dart';

// needs to be StatefulWidget, so we can keep track of the count of the fields internally
class PlayerList extends StatefulWidget {
  const PlayerList({
    this.initialCount = 5,
  });

  // also allow for a dynamic number of starting players
  final int initialCount;

  @override
  _PlayerListState createState() => _PlayerListState();
}

class _PlayerListState extends State<PlayerList> {
  int fieldCount = 0;
  int nextIndex = 0;
  // you must keep track of the TextEditingControllers if you want the values to persist correctly
  List<TextEditingController> controllers = <TextEditingController>[];

  // create the list of TextFields, based off the list of TextControllers
  List<Widget> _buildList() {
    int i;
    // fill in keys if the list is not long enough (in case we added one)
    if (controllers.length < fieldCount) {
      for (i = controllers.length; i < fieldCount; i++) {
        controllers.add(TextEditingController());
      }
    }

    i = 0;
    // cycle through the controllers, and recreate each, one per available controller
    return controllers.map<Widget>((TextEditingController controller) {
      int displayNumber = i + 1;
      i++;
      return TextField(
        controller: controller,
        maxLength: 20,
        decoration: InputDecoration(
          labelText: "Player $displayNumber",
          counterText: "",
          prefixIcon: const Icon(Icons.person),
          suffixIcon: IconButton(
            icon: Icon(Icons.clear),
            onPressed: () {
              // when removing a TextField, you must do two things:
              // 1. decrement the number of controllers you should have (fieldCount)
              // 2. actually remove this field's controller from the list of controllers
              setState(() {
                fieldCount--;
                controllers.remove(controller);
              });
            },
          ),
        ),
      );
    }).toList(); // convert to a list
  }


  @override
  Widget build(BuildContext context) {
    // generate the list of TextFields
    final List<Widget> children = _buildList();

    // append an 'add player' button to the end of the list
    children.add(
      GestureDetector(
        onTap: () {
          // when adding a player, we only need to inc the fieldCount, because the _buildList()
          // will handle the creation of the new TextEditingController
          setState(() {
            fieldCount++;
          });
        },
        child: Container(
          color: Colors.blue,
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Text(
              'add player',
              style: TextStyle(
                color: Colors.white,
              ),
            ),
          ),
        ),
      ),
    );

    // build the ListView
    return ListView(
      padding: EdgeInsets.all(0),
      shrinkWrap: true,
      physics: NeverScrollableScrollPhysics(),
      children: children,
    );
  }

  @override
  void initState() {
    super.initState();

    // upon creation, copy the starting count to the current count
    fieldCount = widget.initialCount;
  }

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

  @override
  void didUpdateWidget(PlayerList oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }
}

通过上述操作,您可以:

With the above, you can:


  • 启动应用程序

  • 将播放器2更改为 bob

  • 将玩家3更改为史蒂夫

  • 将玩家4更改为查尔斯

  • 删除玩家3

  • 观察到玩家2是'bob',新玩家3是'charles'

  • start the app
  • change player 2 to 'bob'
  • change player 3 to 'steve'
  • change player 4 to 'charles'
  • delete player 3
  • observe that player 2 is 'bob' and the new player 3 is 'charles'

我认为这就是您在这里寻找的东西

I think this is what you are looking for here.

这篇关于当onPressed按钮时如何从ListView中删除TextField?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆