如何使选定项目中的文本在Flutter的文本字段内

问题描述

我有一个编辑功能,可在扑朔迷离的待办事项列表应用程序的对话框中显示。选择一个项目进行编辑时,将出现一个对话框,其中包含一个TextField(用于输入所选项目的新值)和一个按钮(用于保存更改)。目标是将所选项目的文本放在对话框的TextField上,当前,我的代码在TextField内有一个hintText,它确实显示所选项目的值,但我要实现的是将其放在控制器中。

如果您不了解我想要实现的功能,请参见instagram的编辑功能,在instagram上编辑帖子时,无需再次键入所有内容,而在编辑时则具有该帖子的原始文本。嗯,这在我的应用程序上没有发生,在编辑项目时,TextField不显示任何内容。我该如何工作?

与编辑功能相关的代码

  List<TodoElement> _todoItems = [];
  TextEditingController _editController = TextEditingController();

  void _editTodoItem(String newText,int index) {
    setState(() {
      _todoItems[index].task = newText;
    });
  }

  _editDialog(BuildContext context,int index) {
    return showDialog(context: context,builder: (context){
      return Dialog(
        backgroundColor: Colors.transparent,insetAnimationDuration:
          const Duration(milliseconds: 800),child: Container(
          padding: EdgeInsets.all(20),height: 180,width: 100,child: Column(
            mainAxisAlignment: MainAxisAlignment.center,children: [
                Container(
                  height: 60,child: TextField(  // this is the textfield that I should have the text of the selected item inside.
                    controller: _editController,autofocus: true,autocorrect: false,onSubmitted: (val) {
                      FocusScope.of(context).requestFocus(FocusNode());
                      _editTodoItem(val,index);
                      Navigator.of(context).pop();
                    },decoration: Inputdecoration(
                      hintText: '${_todoItems[index].task}',//this hint text shows the value of the selected item,yhis is what I want to have but in the controller.
                      enabledBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(12.0)),borderSide: BorderSide(color: Colors.red,width: 2),),focusedBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(12.0)),)
                ),Container(
                  height: 65,width: double.infinity,margin: EdgeInsets.only(top: 5,child: RaisedButton(
                    textColor: Colors.white,color: Colors.red,child: Text('EDIT',style: TextStyle(fontSize: 18)),onpressed: () {
                      _editTodoItem(_editController.text,index);
                      FocusScope.of(context).requestFocus(FocusNode());
                      Navigator.of(context).pop();
                    },],);
    });
  }

完整的main.dart

import 'package:Flutter/material.dart';

class TodoElement {
  String task;
  final DateTime timeOfCreation;

  TodoElement(this.task,this.timeOfCreation);
}

void main() => runApp(MaterialApp(home: MyApp()));

class MyApp extends StatefulWidget {
  @override
  createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  List<TodoElement> _todoItems = [];
  TextEditingController _controller = TextEditingController();
  TextEditingController _editController = TextEditingController();

  void _addTodoItem(String task) {
    if(task.isNotEmpty) {
      setState(() {  
        _todoItems.add(TodoElement(task,DateTime.Now()));
      });
    }
  }

  void _editTodoItem(String newText,int index) {
    setState(() {
      _todoItems[index].task = newText;
    });
  }

  void _removetodoItem(int index) {
    setState(() => _todoItems.removeAt(index));
  }

  _editDialog(BuildContext context,shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20)
        ),child: Container(
          decoration: Boxdecoration(
            color: Colors.white,borderRadius: BorderRadius.all(Radius.circular(20.0)),padding: EdgeInsets.all(20),child: TextField(
                    controller: _editController,style: TextStyle(fontSize: 17,enabledBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(12.0)),shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.all(Radius.circular(12)),);
    });
  }

  Widget _buildTodoItem(String todoText,int index) {
    return SizedBox(
      child: Container(
        height: 58,margin: EdgeInsets.only(left: 22.0,right: 22.0,bottom: 12,decoration: Boxdecoration(
          border: Border.all(width: 1.5,color: Colors.red),borderRadius: BorderRadius.all(Radius.circular(18)),child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,children:[
            Expanded(
              child: ListTile(
                title: Text(
                  todoText,style: TextStyle(fontSize: 18),onTap: () => null,FlatButton(
              child: Text('Edit',style: TextStyle(color: Colors.red,fontSize: 16.5),onpressed: () => _editDialog(context,index),FlatButton(
              child: Text('Delete',onpressed: () => _removetodoItem(index),);
  }

  int compareElement(TodoElement a,TodoElement b) =>
      a.timeOfCreation.isAfter(b.timeOfCreation) ? -1 : 1;

  Widget _buildTodoList() {
    _todoItems.sort(compareElement);
    return Expanded(
      child: ListView.builder(
        itemCount: _todoItems.length,itemBuilder: (context,index) {
          if (index < _todoItems.length) {
            return _buildTodoItem(_todoItems[index].task,index);
          }
        },);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: PreferredSize(
          preferredSize: Size.fromHeight(50),child: AppBar(
            centerTitle: true,backgroundColor: Colors.red,title: Text('To Do List',style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold,)
        ),backgroundColor: Colors.white,body: GestureDetector(
          onTap: () {
            FocusScope.of(context).requestFocus(FocusNode());
          },child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,children: [
              Container(
                height: 60,margin: EdgeInsets.all(22),child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,children: [
                    Expanded(
                      flex: 10,child: Container(
                        height: double.infinity,child: TextField(
                          controller: _controller,onSubmitted: (val) {
                            _addTodoItem(val);
                            _controller.clear();
                          },style: TextStyle(fontSize: 18,decoration: Inputdecoration(
                            hintText: 'Add a task here...',enabledBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.all(Radius.circular(12.0)),focusedBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.all(Radius.circular(12.0)),Expanded(
                      flex: 4,margin: EdgeInsets.only(left: 12),child: RaisedButton(
                          textColor: Colors.white,child: Text('ADD',shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.all(Radius.circular(12)),onpressed: () {
                            _addTodoItem(_controller.text);
                            _controller.clear();
                            FocusScope.of(context).requestFocus(FocusNode());
                          },_buildTodoList()
            ]
          ),);
  }
}

As you can see in this image the dialog has popup and now as a hintText there is the value of the selected item,I need to have it in form of a controller so that there is actual text

如果您有任何疑问,请在评论中让我知道;)

解决方法

您已经有了_editController变量。您不仅可以使用它获取键入的文本,还可以设置它:

您可以在调用编辑功能之前执行此操作,例如:

[...]
onPressed: () {    
                   _editController.text = toDoText;
                   _editDialog(context,index);
},[...]

(或者,如果愿意,也可以在创建对话框之前。)

documentation中可以看到:

TextEditingController也可以用于为文本字段提供初始值。如果使用已具有文本的控制器来构建文本字段,则该文本字段将使用该文本作为其初始值。