Flutter 文本编辑控制器 listview.builder

Posted

技术标签:

【中文标题】Flutter 文本编辑控制器 listview.builder【英文标题】:flutter text editing controller listview.builder 【发布时间】:2021-09-19 04:07:06 【问题描述】:

我希望该页面显示一个社交媒体应用列表,用户可以在其中输入他们的用户名/详细信息。我希望能够提取此输入数据以及应用名称和徽标(最好是 JSON 文件),以便能够将它们创建为通向相应应用和配置文件的按钮。

为此,我使用 listview.builder 创建了一个列表图块列表(来自一个单独的列表,其中包含我想要包含的应用程序和徽标的列表)并使用副标题为每个列表图块添加了一个 TextField功能。

请您帮我将文本编辑控制器添加到列表的每个项目中,并提取一个包含文本输入、应用名称和徽标的文件。

请注意:应用列表是一个包含应用名称、TextField 提示文本和徽标图像的列表。

import 'package:flutter/material.dart';
import 'package:applist/apps.dart';

class AppList extends StatefulWidget 
  const AppList(Key? key) : super(key: key);

  @override
  _AppListState createState() => _AppListState();


class _AppListState extends State<AppList> 
  @override
  void initState() 
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('My list of apps'),
      ),
      body: Padding(
        padding: EdgeInsets.all(20.0),
        child: Column(
          children: [
            Expanded(
                child: ListView.builder(
                    itemCount: apps.length,
                    itemBuilder: (BuildContext context, int index) 
                      return ListTile(
                        title: Text(apps[index].appname),
                        leading: SizedBox(
                          height: 50,
                          width: 50,
                          child: Image.asset(apps[index].image),
                        ),
                        subtitle: TextField(
                          decoration:
                              InputDecoration(hintText: (apps[index].hint)),
                        ),
                      );
                    ))
          ],
        ),
      ),
    );
  

【问题讨论】:

【参考方案1】:

1-你需要定义TextEditingConrtoller字段变量:

late  TextEditingController textEditingController ; 

2-初始化initState中的字段变量

  @override
  void initState()
    super.initState();
    textEditingController = TextEditingController();
  

3- 然后初始化你的 TextField 控制器

TextField(
   controller:textEditingController ,
)
你的最终代码应该是这样的
import 'package:flutter/material.dart';
import 'package:applist/apps.dart';

class AppList extends StatefulWidget 
  const AppList(Key? key) : super(key: key);

  @override
  _AppListState createState() => _AppListState();


class _AppListState extends State<AppList> 
late  TextEditingController textEditingController ;   // <--
@override
  void initState() 
    super.initState();
    textEditingController = TextEditingController(); // <--
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('My list of apps'),
      ),
      body: Padding(
        padding: EdgeInsets.all(20.0),
        child: Column(
          children: [
            Expanded(
                child: ListView.builder(
                    itemCount: apps.length,
                    itemBuilder: (BuildContext context, int index) 
                      return ListTile(
                        title: Text(apps[index].appname),
                        leading: SizedBox(
                          height: 50,
                          width: 50,
                          child: Image.asset(apps[index].image),
                        ),
                        subtitle: TextField(
                          controller:textEditingController , // <--
                          decoration:
                              InputDecoration(hintText: (apps[index].hint)),
                        ),
                      );
                    ))
          ],
        ),
      ),
    );
  

【讨论】:

非常感谢!我不再收到错误,这很好,但是如何为列表中的每个文本字段创建唯一的文本编辑控制器?在我编辑一个时,所有其他 texfields 都会互惠。您的建议/帮助将不胜感激:) 而不是一个文本控制器,如果索引足以区分每个控制器,则需要预先初始化的控制器 List,如果不使用 Map 而不是 dart late final List&lt;TextEditingController&gt; controllers; 初始化每个 @ 987654331@【参考方案2】:

让每个应用都有一个唯一的 id(如果只有应用名称不是唯一的)。

创建TextEditingController的地图

Map<String, TextEditingController> _textControllers = new Map();

为您的每个应用添加一个新的 TextEditingController,并以它的唯一名称或 id 作为键

apps.forEach((app) => textControllers[app.id] = new TextEditingController());

最后你可以像这样在你的 ListViewBuilder 中使用它..

ListView.builder(
          itemCount: apps.length,
          itemBuilder: (context, index) => TextFormField(
            controller: _textControllers[apps[index].id],
          ),
        )

【讨论】:

非常感谢!我会试试这个!【参考方案3】:

如果您想对文本字段使用唯一的控制器。 您应该使用具有控制器和其他数据的模型。 使用“冻结”的模型示例

import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'controller_model.freezed.dart';

@freezed
class ControllerModel with _$ControllerModel 
  const factory ControllerModel(
    required String name,
    required TextEditingController controller,
  ) = _ControllerModel;

【讨论】:

以上是关于Flutter 文本编辑控制器 listview.builder的主要内容,如果未能解决你的问题,请参考以下文章

编辑文本控制器更新小部件值而不调用 setState() - Flutter

ListView 包含一个多行文本字段,后跟 Flutter 中的 ListTiles

如何使用控制器 ListView Flutter

Flutter控件——常用控件:TextField

Flutter控件——常用控件:TextField

禁用颤振中的文本编辑字段