【问题标题】:Not able to use a List present in another widget无法使用另一个小部件中存在的列表
【发布时间】:2021-11-23 14:50:26
【问题描述】:

我正在制作一个列表应用程序,它是一个项目列表,后跟一个复选框。然后有一个带有加号的浮动操作按钮。点击它你会得到一个底部表。在底部表中,你可以输入你的任务textField 。单击添加按钮时,任务会被添加。 ui 长这样

我无法从 add_taskScreen.dart 访问 task_screen.dart 中定义的 tasks List。尽管导入了所需的文件,但我收到以下错误

error: Undefined name 'tasks'. (undefined_identifier at [todoey_flutter] lib\add_task_screen.dart:43)

这是我的代码

Main.dart

import 'package:flutter/material.dart';
import 'tasks_screen.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return  const MaterialApp(
      home: TaskScreen(),
    );
  }
}

Task_tile.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class TaskTile extends StatelessWidget {
  @override
 late final  bool isChecked ;
  late final String taskTitle;
  final Function checkBoxCallBack;
  TaskTile({required this.isChecked,required this.taskTitle,required this.checkBoxCallBack});
  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(taskTitle,
      style:TextStyle(
        decoration:  isChecked ? TextDecoration.lineThrough:null
      ),
      ),
      trailing:  Checkbox(
      value:isChecked,
    activeColor:Colors.lightBlueAccent,
    onChanged: (newValue) {//onChanged here if we select the check box the value becomes true else it will become false
      checkBoxCallBack(newValue);//widget.toggleCheckBoxState(value);
    },
      )
    );
  }
}

Task_list.dart

     import 'package:flutter/material.dart';
import 'task_title.dart';
import 'Models/task.dart';
class TaskList extends StatefulWidget {

  final List<Task> tasks;
  TaskList(this.tasks);

  @override
  State<TaskList> createState() => _TitleListState();
}

class _TitleListState extends State<TaskList> {



  @override
  Widget build(BuildContext context) {
    return ListView.builder(itemBuilder: (context,index){//in the listView Builder index is already defined and gets updated by itself
    return TaskTile(
      taskTitle:widget.tasks[index].name,
      isChecked: widget.tasks[index].isDone,
      checkBoxCallBack:(bool checkBoxState){
        setState((){
          widget.tasks[index].toggleDone() ;
        });
      }
    );
    },
    itemCount: widget.tasks.length,//max no tasks that can fit in the screen ie..how many ever tasks are there on 'tasks' it will build that many
    );
  }
}
    

task.dart

import 'package:flutter/material.dart';
class Task{
  late final String name;
  late bool isDone;

  Task
      ({required this.name,this.isDone=false});//give a default value to isDone

  void toggleDone()
 {
  isDone = !isDone;
 }
}

task_Screen.dart

import 'package:flutter/material.dart';
import 'tasks_list.dart';
import 'add_task_screen.dart';
import 'package:todoey_flutter/Models/task.dart';
class TaskScreen extends StatefulWidget {
  const TaskScreen({Key? key}) : super(key: key);

  @override
  State<TaskScreen> createState() => _TaskScreenState();
}

    class _TaskScreenState extends State<TaskScreen> {
      List<Task> tasks = [
        Task(name: 'Buy milk'),
        Task(name: 'Buy eggs'),
        Task(name: 'Buy bread'),
      ];
      @override
      Widget build(BuildContext context) {
        return  Scaffold(//Scaffold contains everything
          backgroundColor: Colors.lightBlueAccent,
          body:Column(
            children: [
              Container(
                padding:const EdgeInsets.only(top:60,left:30,right:30,bottom: 30),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                    children:const <Widget>[
                       CircleAvatar(
                         child: Icon(
                           Icons.list,
                         color: Colors.lightBlueAccent,
                         size:30.0,
                       ),
                       backgroundColor:Colors.white,
                         radius:30,
                       ),
                     SizedBox(height:10),
                     Text(
                       'Todoey',
                     style:TextStyle(
                       color:Colors.white,
                       fontSize: 50,
                       fontWeight: FontWeight.w700,
                     )
                     ),
                      Text('12 Tasks',
                      style:TextStyle(
                        color:Colors.white,
                        fontSize: 18,
                      )
                      ),
    
                   ]
                ),
              ),
              Expanded(
                child: Container(//designing the white part of the todoey
                  padding:const EdgeInsets.symmetric(horizontal: 20),
                  height:300,
                  decoration: const BoxDecoration(
                      color:Colors.white,
                      borderRadius: BorderRadius.only(
                        topLeft:Radius.circular(20.0),
                        topRight:Radius.circular(20.0),
                      ),
                  ),
                  child: TaskList(tasks),
        ),
                ),
            ],
          ),
          floatingActionButton: FloatingActionButton(
           backgroundColor:Colors.lightBlueAccent,
            child: const Icon(
              Icons.add,
            ),
            onPressed: (){ //call the bottomSheet in builder
             showModalBottomSheet(builder:(context)=>AddTaskScreen(
                     (newTaskTitle)
                 {
               setState(){
                 tasks.add(Task(name:newTaskTitle));
               }
             }), context: context);//to create bottom drawer widget on pressing the button a new pop up appears at the bottom
            },
          ),
        );
      }
    }

add_Task_Screen.dart

import 'package:flutter/material.dart';
import 'task_title.dart';
import 'tasks_list.dart';
import 'tasks_screen.dart';
import 'package:todoey_flutter/Models/task.dart';
class AddTaskScreen extends StatelessWidget {
  late String newTaskTitle;
  final Function addTaskCallBack;
  AddTaskScreen( this.addTaskCallBack, {Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(20.0),
      child: Container(
      //color:const Color(0xff757575),//you cant add color 2 times it will throw an exception
          decoration:const BoxDecoration(
          color:  Colors.white,
          borderRadius: BorderRadius.only(topLeft:Radius.circular(20.0) ,topRight:Radius.circular(20.0)),
        ),
        child:Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children:[
            const Center(
              child: Text('Add Task',
              style: TextStyle(
                fontSize:30.0,
                color:Colors.lightBlueAccent,
              ),
              ),
            ),
             TextField(
              autofocus: true,
                autocorrect: true,
              textAlign: TextAlign.center,
              onChanged: (newText){
               newTaskTitle = newText;
              },
            ),
            FlatButton(
              onPressed: (){

                print(newTaskTitle);
                tasks.add(name:newTaskTitle);//here is the error 
              },
              child: const Text('Add'),
              color: Colors.lightBlueAccent,
            )
          ]
        )
      ),
    );
  }
}

【问题讨论】:

  • 如果我正确理解你的代码,我认为你应该使用addTaskCallBack 而不是在add_Task_Screen.dart 中调用tasks.add(name:newTaskTitle)。因为您将tasks.add 方法作为参数传递给add_Task_Screen.darttask_Screen.dart
  • @EricAig 但是任务没有被添加到屏幕上
  • 可以添加tasks.add的代码吗??如果它是一个异步方法,你可能需要在调用 setState 之前等待它
  • @EricAig 我已经在代码中添加了 .tasks 基本上是一个“任务”列表
  • 哦,是的,对不起,我错过了。你试过我的第一个建议吗?通过在add_Task_Screen.dart中使用addTaskCallBack

标签: flutter android-studio dart flutter-layout flutter-dependencies


【解决方案1】:

在 task_screen.dart 中创建这样的函数

void _handleAddTask(String _name)=>setState(()=>tasks.add(Task(name: _name))));

然后将showModalBottomSheet修改成这样

showModalBottomSheet(builder:(context)=>AddTaskScreen(_handleAddTask,"Add task"), context: context);},),);}}

add_Task_Screen.dart,修改 AddTaskScreen( this.addTaskCallBack, {Key? key}) : super(key: key);这个

AddTaskScreen( this.addTaskCallBack, this.newTaskTitle, {Key? key}) : super(key: key);

为您的 TextField 创建一个 TextEditingController 并像这样将其传递给它

TextField(
              autofocus: true,
controller: _textFieldController,
                autocorrect: true,
              textAlign: TextAlign.center,
              onChanged: (newText){
               newTaskTitle = newText;
              },
            ),

最后,在添加按钮的onPress中,修改成这样:

            FlatButton(
              onPressed: (){

                print(newTaskTitle);
addTaskCallBack(_textFieldController.text);
              },
              child: const Text('Add'),
              color: Colors.lightBlueAccent,
            )

【讨论】:

  • 谢谢队友。这终于奏效了。非常感谢。你能解释一下你是否在那里添加了一个控制器。我是初学者。所以请原谅我问了一些愚蠢的问题。:)
  • 我添加了一个控制器,以便您在点击“添加”按钮时能够获取文本输入的当前值。您也可以使用变量来完成此操作,并在TextField 小部件的onSubmittedonChanged 属性中设置它的当前值。
【解决方案2】:

子小部件中不存在任务列表。您可以通过您提供的回调方法访问小部件。 将您的 FlatButton 重构为如下所示:

FlatButton(
  onPressed: () {
    addTaskCallBack(newTaskTitle);
  },
  child: const Text('Add'),
  color: Colors.lightBlueAccent,
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 2021-03-30
    • 2014-09-01
    相关资源
    最近更新 更多