Generate TextFields on demand with Stateless widgets and GetX in Flutter

huangapple go评论81阅读模式
英文:

Generate TextFields on demand with Stateless widgets and GetX in Flutter

问题

思路是使用GetX与无状态小部件(Stateless widgets)结合,在需要时动态生成文本字段(TextFields)。

GetX表示,如果我们使用它的状态管理,就不需要使用有状态小部件(Stateful widgets)。

在点击"+"按钮时,我希望一个文本字段被添加到列表中。目前在点击"+"按钮时没有任何反应。

请指出错误所在。

通过GetX实现这个的正确方法是什么?

这是屏幕文件:

import 'package:flutter/material.dart';
import 'package:dynamic_lists/controllers/2_ListWithInputBoxGetxController.dart';
import 'package:get/get.dart';

class ListWithInputBoxGetx extends StatelessWidget {
  ListWithInputBoxGetx({Key? argKey, this.title}) : super(key: argKey);

  final String? title;
  ListWithInputBoxGetxController controller =
      Get.put(ListWithInputBoxGetxController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(title!)),
      body: Padding(
          padding: const EdgeInsets.all(10),
          child: SingleChildScrollView(
              child: Column(
            children: <Widget>[
              Container(
                  height: 400,
                  color: Colors.limeAccent,
                  child: ListView.builder(
                      itemCount: controller.textFieldControllerList.length,
                      prototypeItem: const TextField(),
                      itemBuilder: ((context, index) {
                        return Obx(() => TextField(
                              controller: controller.getTextFieldController(
                                  index), 
                            ));
                      }))),
              const SizedBox(height: 10),
              ElevatedButton(
                  onPressed: controller.addTextField, child: const Text("+")),
              const SizedBox(height: 10),
              ElevatedButton(
                  onPressed: controller.submit,
                  child: const Icon(Icons.sailing))
            ],
          ))),
    );
  }
}

这是控制器文件:

import 'package:get/get.dart';
import 'package:flutter/material.dart';

class ListWithInputBoxGetxController extends GetxController {
  RxList<TextEditingController> textFieldControllerList =
      <TextEditingController>[].obs;

  TextEditingController getTextFieldController(argIndex) {
    return textFieldControllerList[argIndex];
  }

  void addTextField() {
    textFieldControllerList.add(TextEditingController());
  }

  void submit() {}
}
英文:

Idea is to use GetX with Stateless widgets and generate TextFields on demand.

GetX says that if we use its state management then we won't require Stateful widgets.

On the click of the + button, I want a TextField to get added to the List. Currently nothing is happening on the click of the + button.

Please point out the error.

What is the proper way to achieve this through GetX?

This is the screen file:

import &#39;package:flutter/material.dart&#39;;
import &#39;package:dynamic_lists/controllers/2_ListWithInputBoxGetxController.dart&#39;;
import &#39;package:get/get.dart&#39;;

class ListWithInputBoxGetx extends StatelessWidget {
  ListWithInputBoxGetx({Key? argKey, this.title}) : super(key: argKey);

  final String? title;
  ListWithInputBoxGetxController controller =
      Get.put(ListWithInputBoxGetxController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(title!)),
      body: Padding(
          padding: const EdgeInsets.all(10),
          child: SingleChildScrollView(
              child: Column(
            children: &lt;Widget&gt;[
              Container(
                  height: 400,
                  color: Colors.limeAccent,
                  child: ListView.builder(
                      itemCount: controller.textFieldControllerList.length,
                      prototypeItem: const TextField(),
                      itemBuilder: ((context, index) {
                        return Obx(() =&gt; TextField(
                              controller: controller.getTextFieldController(
                                  index), 
                            ));
                      }))),
              const SizedBox(height: 10),
              ElevatedButton(
                  onPressed: controller.addTextField, child: const Text(&quot;+&quot;)),
              const SizedBox(height: 10),
              ElevatedButton(
                  onPressed: controller.submit,
                  child: const Icon(Icons.sailing))
            ],
          ))),
    );
  }
}

This is the controller file:

import &#39;package:get/get.dart&#39;;
import &#39;package:flutter/material.dart&#39;;

class ListWithInputBoxGetxController extends GetxController {
  RxList&lt;TextEditingController&gt; textFieldControllerList =
      &lt;TextEditingController&gt;[].obs;

  TextEditingController getTextFieldController(argIndex) {
    return textFieldControllerList[argIndex];
  }

  void addTextField() {
    textFieldControllerList.add(TextEditingController());
  }

  void submit() {}
}

答案1

得分: 1

好的,以下是翻译好的内容:

解决方案是将Obx包裹在ListView.builder周围,而不是在ListView内部的TextField周围。

Container(
  height: 400,
  color: Colors.limeAccent,
  child: Obx(() => ListView.builder(
    itemCount: controller.textFieldControllerList.length,
    prototypeItem: const TextField(),
    itemBuilder: ((context, index) {
      return TextField(
        controller: controller.getTextFieldController(index),
      );
    })
  ))
)
英文:

Well, the solution is to wrap Obx around the ListView.builder, not around the TextField inside the ListView.

Container(
                  height: 400,
                  color: Colors.limeAccent,
                  child: Obx(() =&gt; ListView.builder(
                      itemCount: controller.textFieldControllerList.length,
                      prototypeItem: const TextField(),
                      itemBuilder: ((context, index) {
                        return TextField(
                          controller: controller.getTextFieldController(index),
                        );
                      })))),

答案2

得分: 0

你可以使用这段代码,这段代码是你的代码的修改版本。

class ListWithInputBoxGetx extends StatelessWidget {
  ListWithInputBoxGetx({Key? argKey, this.title}) : super(key: argKey);

  final String? title;
  ListWithInputBoxGetxController controller =
      Get.put(ListWithInputBoxGetxController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(title!)),
      body: Padding(
        padding: const EdgeInsets.all(10),
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Container(
                height: 400,
                color: Colors.limeAccent,
                child: Obx(
                  () => ListView.builder(
                    itemCount: controller.textfieldList.length,
                    prototypeItem: const TextField(),
                    itemBuilder: ((context, index) {
                      return controller.textfieldList[index];
                    }),
                  ),
                ),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: () {
                  controller.addTextField(TextEditingController());
                },
                child: const Text("+"),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: controller.submit,
                child: const Icon(Icons.sailing),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class ListWithInputBoxGetxController extends GetxController {
  List textfieldList = [].obs;
  void addTextField(TextEditingController controller) {
    textfieldList.add(TextField(
      controller: controller,
    ));
  }

  void submit() {}
}

它的效果如下图所示:

Generate TextFields on demand with Stateless widgets and GetX in Flutter

英文:

You can use this code, this code is the edited version of your code

class ListWithInputBoxGetx extends StatelessWidget {
ListWithInputBoxGetx({Key? argKey, this.title}) : super(key: argKey);

final String? title;
ListWithInputBoxGetxController controller =
  Get.put(ListWithInputBoxGetxController());
@override
Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(title: Text(title!)),
  body: Padding(
      padding: const EdgeInsets.all(10),
      child: SingleChildScrollView(
          child: Column(
        children: &lt;Widget&gt;[
          Container(
              height: 400,
              color: Colors.limeAccent,
              child: Obx(
                () =&gt; ListView.builder(
                    itemCount: controller.textfieldList.length,
                    prototypeItem: const TextField(),
                    itemBuilder: ((context, index) {
                      return controller.textfieldList[index];
                    })),
              )),
          const SizedBox(height: 10),
          ElevatedButton(
              onPressed: () {
                controller.addTextField(TextEditingController());
              },
              child: const Text(&quot;+&quot;)),
          const SizedBox(height: 10),
          ElevatedButton(
              onPressed: controller.submit,
              child: const Icon(Icons.sailing))
        ],
      ))),
);
}
}
 class ListWithInputBoxGetxController extends GetxController {
 List textfieldList = [].obs;
 void addTextField(TextEditingController controller) {
 textfieldList.add(TextField(
  controller: controller,
 ));
 }

void submit() {}
}

it looks like this

Generate TextFields on demand with Stateless widgets and GetX in Flutter

huangapple
  • 本文由 发表于 2023年8月8日 23:27:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76861022.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定